Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Two argument bless syntax

by logie17 (Friar)
on Nov 22, 2006 at 16:08 UTC ( [id://585557]=perlquestion: print w/replies, xml ) Need Help??

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

I noticed in a constructor the following code:
my $self = bless {}, ref $class || $class

I've always typed:
my $self = {}; bless $self, $class
Could someone explain to me why the above would be used and why the author may have chose to write a bless that way (opposed to the latter)? It may just be syntatatic preferences, just wanted to make sure I wasn't missing anything else beyond that.
Thanks again,

Replies are listed 'Best First'.
Re: Syntactic Question
by davorg (Chancellor) on Nov 22, 2006 at 16:17 UTC

    It makes your constructor slightly more flexible. It means that as well as calling it as a class method:

    my $foo = SomeClass->new;

    You can also call it as an object method:

    my $bar = $foo->new;

    In general, I'd say that this isn't a good idea. If I want a constructor that can be called as an object method then I'll create a different constructor method with a different (and more meaningful) name - perhaps something like 'clone'.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Hi davorg,

      I would agree with you that should be used a new object called clone if the object was copied to the new object, which do not happen in the specified case.

      I don't like that much allowing new called on a ref/obj, but it is safer to do it that way, that just bless the object with $_[0].

      On the other hand, I think that croak or die with new called on a ref would be a better solution. The usual solution of just bless on $_[0] also die with "Attempt to bless into a reference", so I don't think it matters much.

      Damien Conway weighs in against this in his "Perl Best Practices" book. In the section titled "Cloning", p. 334 he argues that blending object creation and cloning makes it harder to tell what the code is doing, e.g.
      my $obj = $name->new( @args );
      Might be doing creation or cloning depending on whether $name is a string or a reference. Also he makes the point that it complicates the constructor code for no good reason.

      So yeah, this is a slick trick that people used to like, but it's gone out of favor.

      (You can blame Conway for helping to promulgate this idiom: he uses it in places in his earlier work "Object Oriented Perl".)

Re: Two argument bless syntax
by perrin (Chancellor) on Nov 22, 2006 at 16:40 UTC
    It's cargo-cult. Don't do it unless you actually need it for something. See this column by merlyn for more.

      It's cargo-cult style programming, sure. I think we need to be careful about just throwing that answer around willy-nilly, though. It was nice of you to provide a link to an article that discusses object construction, but logie17's specific question doesn't get referenced until the last couple of paragraphs.

      It might be better to give a quick summary of why it's used (1: to allow object construction via an object rather than just as a class/package method; 2: "Cargo-cult" - I saw somebody else do this, so I'm doing it too even though I don't know why), why it's bad (1: construction via the object could mean a few different things, and you should avoid coding techniques that make your intention hard to fathom; 2: You shouldn't write a particular chunk of code if you don't know why you're writing it - if Billy Smith jumped off the Empire State Building, I suppose you would have to jump off the Empire State Building too), and then link to merlyn's article (for more details about object construction). It's probably a good idea to include a link explaining what cargo-cult programming is if you suspect that the questioner (or someone else reading your reply in distant years) is not familiar with the term.

      So many parentheses ...

      Sorry about being so pedantic. I don't think there's anything wrong about your reply, and the link is great. I just want folks to be careful that "It's cargo-cult" doesn't end up becoming a cargo-cult reply.

        Sorry about being so pedantic. I don't think there's anything wrong about your reply, and the link is great. I just want folks to be careful that "It's cargo-cult" doesn't end up becoming a cargo-cult reply.

        FWIW his reply came over 20 minutes after several others that explained things in summary form, so a quick, short link was perfect at that point. If the OP wants to investigate further, great. If not, then there's no great time wasted reinventing an answer that won't be read, esp when merlyn did a good job already...

Re: Two argument bless syntax
by themage (Friar) on Nov 22, 2006 at 16:19 UTC
    Hi logie17,

    The way it is, you are allowed to create a new object using the Class/Module name, os using a pre-existent object.

    Example:
    my $obj1=Some::Class->new(); my $obj2=$obj1->new();

Re: Two argument bless syntax
by Firefly258 (Beadle) on Nov 22, 2006 at 18:20 UTC
    I suppose the author of that decided to be a little pedantic about what he defines to be the object named self i.e. The blessed reference as opposed to the anonymous hash or in otherwords, a member of a class as opposed to a plain old data-structure.

    You might come across a very simple constructor like the following if all that is needed is to return an instantiated object.
    sub new { return bless {}, shift; }
    What I don't see is why the author supposes $class might be a reference in ref $class || $class. The first argument to a constructor is usually always a literal string representing the class name and i'm betting that ref $class is redundant there as it evaluates to false.
      and i'm betting that ref $class is redundant there as it evaluates to false

      Not necessarily. See davorg's and themage's replies here and here.

      Cheers,

      JohnGG

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-25 08:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found