What is the difference between new Some::Class and Some::Class->new() in Perl?

后端 未结 4 1539
我在风中等你
我在风中等你 2020-11-29 08:27

Many years ago I remember a fellow programmer counselling this:

new Some::Class;    # bad! (but why?)

Some::Class->new(); # good!

Sadly

相关标签:
4条回答
  • 2020-11-29 08:37

    Using new Some::Class is called "indirect" method invocation, and it's bad because it introduces some ambiguity into the syntax.

    One reason it can fail is if you have an array or hash of objects. You might expect

    dosomethingwith $hashref->{obj}
    

    to be equal to

    $hashref->{obj}->dosomethingwith();
    

    but it actually parses as:

    $hashref->dosomethingwith->{obj}
    

    which probably isn't what you wanted.

    Another problem is if there happens to be a function in your package with the same name as a method you're trying to call. For example, what if some module that you use'd exported a function called dosomethingwith? In that case, dosomethingwith $object is ambiguous, and can result in puzzling bugs.

    Using the -> syntax exclusively eliminates these problems, because the method and what you want the method to operate upon are always clear to the compiler.

    0 讨论(0)
  • 2020-11-29 08:42

    The indirect object syntax is frowned upon, for good reasons, but that's got nothing to do with constructors. You're almost never going to have a new() function in the calling package. Rather, you should use Package->new() for two other (better?) reasons:

    1. As you said, all other class methods take the form Package->method(), so consistency is a Good Thing

    2. If you're supplying arguments to the constructor, or you're taking the result of the constructor and immediately calling methods on it (if e.g. you don't care about keeping the object around), it's simpler to say e.g.

    $foo = Foo->new(type => 'bar', style => 'baz');
    Bar->new->do_stuff;
    

    than

    $foo = new Foo(type => 'bar', style => 'baz');
    (new Bar)->do_stuff;
    
    0 讨论(0)
  • 2020-11-29 08:48

    See Indirect Object Syntax in the perlobj documentation for an explanation of its pitfalls. freido's answer covers one of them (although I tend to avoid that with explicit parens around my function calls).

    Larry once joked that it was there to make the C++ feel happy about new, and although people will tell you not to ever use it, you're probably doing it all the time. Consider this:

    print FH "Some message";
    

    Have you ever wondered my there was no comma after the filehandle? And there's no comma after the class name in the indirect object notation? That's what's going on here. You could rewrite that as a method call on print:

    FH->print( "Some message" );
    

    You may have experienced some weirdness in print if you do it wrong. Putting a comma after the explicit file handle turns it into an argument:

    print FH, "some message";     # GLOB(0xDEADBEEF)some message
    

    Sadly, we have this goofiness in Perl. Not everything that got into the syntax was the best idea, but that's what happens when you pull from so many sources for inspiration. Some of the ideas have to be the bad ones.

    0 讨论(0)
  • Another problem is that new Some::Class happens at run time. If there is an error and you testing never branches to this statement, you never know it until it happens in production. It is better to use Some::Class->new unless you are doing dynamic programing.

    0 讨论(0)
提交回复
热议问题