Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

OO style: Placement of "new"

by crenz (Priest)
on Apr 07, 2003 at 13:20 UTC ( [id://248586]=perlquestion: print w/replies, xml ) Need Help??

crenz has asked for the wisdom of the Perl Monks concerning the following question:

Just wondering -- I keep seeing different syntaxes for creating objects:

my $obj = My::Module->new(); #1

vs.

my $obj = new My::Module; #2

but I haven't found any documentation about the second case. It seems that I can just use any method name, as in

my $res = some_method $obj;

which looks somewhat weird. Is there a rationale or even benefit behind this syntax, or is it just syntactic sugar for the $obj->some_method notation?

What do people prefer to create objects -- syntax #1 or #2? Personally, I think #2 looks sexier, but I'd like to have a rational reason to use it ;-)

Replies are listed 'Best First'.
Re: OO style: Placement of "new"
by broquaint (Abbot) on Apr 07, 2003 at 13:26 UTC
    Is there a rationale or even benefit behind this syntax, or is it just syntactic sugar for the $obj->some_method notation?
    Indeed, your second code example is demonstrating 'indirect method invocation' by way of using an 'indirect object', which is syntactic sugar for all the C++ (and the like) types. For more info on the subject do a search for 'indirect object' and specifically see tye's node on why it's not generally a great idea.
    HTH

    _________
    broquaint

Re: OO style: Placement of "new"
by Abigail-II (Bishop) on Apr 07, 2003 at 13:28 UTC
    Don't use syntax 2 (also known as "indirect object method"). For reasons why you shouldn't use it, read the section named Indirect Object Syntax in the perlobj manual page.

    Abigail

      I fail to see any actual prohibition in that section, at least, not on class methods. To be honest, most of what's said in that section doesn't even belong in there. The only warning I actually spot against it there, is on that "parens around all parameters" thing:
      new Critter ('Bam' x 2), 1.4, 45
      However, that's precisely the same problem you get when you do
      print ('Bam' x 2), 1.4, 45;
      so that's nothing new.

      OTOH, the one problem I did notice with this "indirect object method", is that it doesn't work with perl's built-in keywords — and likely other predefined subs as well, so the next doesn't call the method "open" in the class "ReadFile":

      my $handle = open ReadFile($file);
      Instead, you have to use
      my $handle = ReadFile->open($file);
      I guess that falls under "the same ambiguity as ordinary list operators", in perlobj.
        The problem isn't precedence. The problem isn't keywords either. The problem is that
        new Foo;

        might call either of

        &new ('Foo'); # Calling new in the current package

        or

        Foo -> new (); # Calling new in Foo, or a parent class

        And there are a bunch of cases that decide which one it will be.

        And no, Perl doesn't like "prohibitions". You are free to do whatever you fancy. But the documentation does give advices on how not to get hurt.

        Abigail

      A blanket prohibition like this is as unwarranted as forbidding the use of $_ on the assertion that it is obfuscation. I use the indirect syntax for constructor calls almost exclusively and I have never encountered the problems described in perlobj.

      crenz, use whatever form suits your tastes or the coding style your project settles upon, and allow the constraints of a particular situation to guide your selection of syntax.


      "The dead do not recognize context" -- Kai, Lexx
        Well, maybe you haven't, but that doesn't mean nobody hasn't, because I have. So it happens in real code.

        Don't use IO notation. It was an interesting experiment, but it failed.

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

Re: OO style: Placement of "new"
by dws (Chancellor) on Apr 08, 2003 at 04:44 UTC
    One of the claims layed against indirect notation comes from perlobj, which says
    For example, calling a method new in indirect notation--as C++ programmers are so wont to do--can be miscompiled into a subroutine call if there's already a new function in scope.
    Perhaps someone can demonstrate how to cause this to happen. I've been using indirect notation for several years now, in 5.005, 5.6, and now 5.8, and have never once seem the wrong subroutine invoked.

    Here's a starting point. Can someone morph this into something that fails?

    package Foo; sub new { print "Foo\n"; bless {} } package Bar; sub new { print "Bar\n"; bless {} } sub addFoo { my $self = shift; $self->{Foo} = new Foo(); # which new gets invoked? } package main; my $bar = new Bar(); $bar->addFoo(); # if there's a bug, this should tickle it
    Anything that fails to print "Foo" constitutes failure.

      Perl tries to detect indirect object syntax using sometimes subtle hints. I was able to break your example easily on the first try:

      > perl indobj.pl Bar Undefined subroutine &Bar::Foo called at indobj.pl line 10.
      What did I do? I simply moved package Foo to be after package Bar. That way Perl doesn't know that Foo is a package name when it compiles the line of code containing new Foo().

                      - tye
        I simply moved package Foo to be after package Bar. That way Perl doesn't know that Foo is a package name ...

        So as long as Perl knows that the target is package name (i.e., if you've gotten your uses and requires right, and haven't made a typo in the name), everything works as expected. Otherwise, you have a slightly harder time debugging. Is that about it?

          A reply falls below the community's threshold of quality. You may see it by logging in.
Re: OO style: Placement of "new"
by crenz (Priest) on Apr 07, 2003 at 15:07 UTC

    Thanks, broquaint and Abigail-II. The arguments in perlobj are definitely convincing.

    After reading tye's post, I think I'll not only continue to use #1, but also switch to HANDLE->print etc. in future.

Re: OO style: Placement of "new"
by derby (Abbot) on Apr 07, 2003 at 16:08 UTC
    it seems that I can just use any method name

    Which is true for case #1 also. There is nothing special about new, it's only by convention that we use it. Your constructor method can be named anything (literally, "anything"). It's just the wrath of downstream programmers that prevent you from doing so.

    And I prefer case #1 for all the reasons all ready pointed out about indirect invocation.

    -derby

Re: OO style: Placement of "new"
by Anonymous Monk on Apr 07, 2003 at 19:29 UTC
    I personally like code that "reads" like natural language, and I've seen comments by Larry that he does also. I can surely read the following:
    my $object = new Thingy; print $log "It works!\n" if $object->is_valid();
    However, the alternative just doesn't read as nicely:
    my $object = Thingy->new; if ($obj->is_valid()) { $log->print("It works!\n"); }
    I do C++, but that's not why I prefer the "new class()" form. It just sounds more like the spoken word. Heck, if I were to slavishly follow C++ syntax, I'd never use the followup 'if' form.

      This is not completely indirect object syntax:

      print $log "It works!\n" if $object->is_valid();

      You would instead write:

      print $log "It works!\n" if is_valid $object;

      Your second snippet would likewise be:

      $log->print( "It works!\n" ) if $obj->is_valid();

      I fail to see how that is less appealing.

Re: OO style: Placement of "new"
by crenz (Priest) on May 01, 2003 at 21:47 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://248586]
Approved by Corion
Front-paged by diotalevi
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2024-04-16 15:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found