Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

confusion about blessing inside a constructor

by edwardt_tril (Sexton)
on Mar 16, 2006 at 20:14 UTC ( [id://537269]=perlquestion: print w/replies, xml ) Need Help??

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

The tie reference and blessing a class to make a n object is
jsut way confusing to me. I have seen sever version of
people using bless in last statement in new() for example :
1. return {bless({},ref($class) || $class)};
2. return bless ($self);
3. return bless{$self,$class};
I am very confused like the concept behind this even after I
have read serveral tutorials on this. I am very used to C++
where the compile will take care of this thing for me. But perl does not...
Oh geees... please enlighten me....

Replies are listed 'Best First'.
Re: confusion about blessing inside a constructor
by chromatic (Archbishop) on Mar 16, 2006 at 20:29 UTC

    They're all wrong. #1 is silly and almost never does the right thing. Ignore it. #2 breaks inheritance. Don't use it. #3 is close, but the presence of the curly braces makes an anonymous hash and it becomes #2 again.

    I prefer:

    bless $self, $class;

    You can use the return if you want to be explicit, but if this is the last statement in the constructor, as it often is, there's no need for return.

    #1 allows you to call the constructor on an existing object to get a new object, but that's almost never useful unless you do other work to make a copy constructor, and if you do that you ought to document it and by the time you go to that trouble, why not just make a separate method that does something else entirely? (Like I said, silly.)

    #2 creates an object in the current package. It ignores the class on which the user called the constructor. Ignoring what the user actually wanted to happen is often a mistake.

    #3 just uses the wrong bracketing characters... I hope.

Re: confusion about blessing inside a constructor
by xdg (Monsignor) on Mar 16, 2006 at 20:28 UTC

    In Perl, there is no pre-defined constructor. More generally, in Perl, an object is just a reference associated with a package (the class). bless is the function that does that. This doesn't even have to be in an constructor.

    my $obj = {}; # empty anonymous hash reference bless $obj, "Some::Class";

    With only one argument, bless associates the reference with the current package, whatever that is.

    package Some::Class; my $obj = {}; bless $obj; # blesses into "Some::Class"

    There is no default constructor in Perl -- though by convention, it's usually called new. When perl calls a method, the invoking object or package name is passed as the first argument.

    $obj->method( 'foo' ); # @_ contains ( $obj, 'foo' ) Some::Class->method( 'foo' ); # @_ contains ( 'Some::Class', 'foo' )

    So the constructor needs to look at the first argument to find the class name. If the first argument is a object (checking ref), the class is the result of ref. Otherwise, the first argument is the class name.

    package Some::Class; sub new { my $first_arg = shift; # get the first argument my $class = ref($first_arg) || $first_arg; my $self = {}; # create a new, anonymous reference; bless $self, $class: # bless it into the class return $self; }

    The variations are mostly shortcuts of all those separate statements. However, if the single-argument form of bless is called, the constructor always blesses into the current package -- which won't work for subclasses. By using the two-argument form, subclasses can inherit new and the object will be properly blessed into the subclass (which is passed as the first argument). Likewise, some people don't like $obj->new() and so don't bother to check ref -- they just require the constructor to only be called as a class method.

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: confusion about blessing inside a constructor
by Roy Johnson (Monsignor) on Mar 16, 2006 at 20:41 UTC
    First, you should understand bless. It makes a variable into an object, which just means that you can call the methods of whatever class you blessed it into via the object itself.

    In example #2, the class that the object is being blessed into is whatever one the constructor physically appears in. That's the default. It's better to have the constructor get the class from the argument list and bless into it explicitly (like example #3), so that some derived class can call the same constructor and still get an object of the derived class.

    Example #1 is too clever for its own good, and is frequently frowned upon as cargo-cult programming (see 408726). It takes the class or an object as an argument, then (if an object) gets the class type before doing the bless.


    Caution: Contents may have been coded under pressure.
Re: confusion about blessing inside a constructor
by GrandFather (Saint) on Mar 16, 2006 at 20:32 UTC

    Take a look at perlobj. Read it through, then seek (0), and read it again.

    A key is to understand that the constructor takes a reference to something, normally a hash or array, and blesses it.

    An important aspect of a blessed object is that when you call a member on it $obj->member ($params) a reference to the object is unshifted into @_ - that is, the first parameter that member gets is $self (== this for C++ people). You have to do a little more leg work than you did in C++: if you need to access your "member data" you have to retreive "this" from the parameter list.

    Now go back and read that documentation again. In the simple case it is simple I assure you. :)


    DWIM is Perl's answer to Gödel
Re: confusion about blessing inside a constructor
by zer (Deacon) on Mar 16, 2006 at 20:31 UTC
    return {bless({},ref($class) || $class)};

    the second argument in bless is the class to be referenced with.

    return bless ($self);

    returns a referance to an object

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://537269]
Approved by Roy Johnson
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-03-28 10:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found