Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: OO Perl: calling a constructor within a class

by jeroenes (Priest)
on Sep 26, 2001 at 14:08 UTC ( [id://114771]=note: print w/replies, xml ) Need Help??


in reply to OO Perl: calling a constructor within a class

The only thing special about a constructor is that it blesses a var. The name 'new' is picked by convention. So no hidden language tricks here.

Just call them at will, make sure you only bless once. Add a check like:

sub new { my $me = shift; if (ref( $me ) eq 'my_class_name') { print "I'm blessed!\n"; } else { ......
Hope this helps,
Jeroen
"We are not alone"(FZ)

Replies are listed 'Best First'.
Re: Re: OO Perl: calling a constructor within a class
by davorg (Chancellor) on Sep 26, 2001 at 14:24 UTC

    Using code like ref($me) eq 'my_class_name' can break inheritance if $me doesn't contain an object of your class, but rather an object of a class that inherits from your class. Far better to use the isa method (from the UNIVERSAL class).

    if (ref($me} && $me->isa('my_class_name')) {
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you don't talk about Perl club."

      In general using this code can cause an error, unless you can be sure that if $me is a reference that it is a blessed reference.

      It is this that led to people doing

      if(ref($me) && UNIVERSAL::isa($me,'my_class_name')) {

      which is ugly, IMO.

      The Scalar::Util package, that as of 5.7.2 is part of the perl distribution, contains a sub blessed() to get around this

      if(blessed($me) && $me->isa('my_class_name')) {

        if(ref($me) && UNIVERSAL::isa($me,'my_class_name')) {

        If you're doing a functional call, then there's no reason for the 'ref($me) &&' in that expression, though I think you get a warning on earlier versions of perl (not sure how early) if '$me' is undefined, so you might say:

        if(defined($me) && UNIVERSAL::isa($me,'my_class_name')) {
        Then again, you could just leave out the first part and turn off warnings locally :-)

        Update: Correction by tye duly noted.
        If I could transfer all the votes/XP from this node to yours I would...(maybe it could be a feature that our overworked fearless leader could implement someday :)

      As merlyn showed me before, you could alternatively use 'can' to check whether $me is an object or not, and leave it alone when it is, trusting that the class of the object is fine:
      if ( ref $me and $me->can('can') ){ .....
      I did have some discussion with tye about can, and at the time he convinced me to use isa instead: ... $me->isa('UNIVERSAL').

      More importantly, reading perlbot I realised that all that caution about bless is unnecessary. So I rephrase my advise above:

      There is nothing special about constructors other than that they bless a variable. Since you are allowed to rebless a variable, just call the constructors at will.
      In perlbot you can find more info and an example of nested constructors.

      Reblessing assumes that the caller knows what (s)he is doing and that the constructor should always return an object of its own class. This antagonizes the logic behind bless-checking. The reblessing approach is the most flexible one, as constructors do not have to make assumptions about which class the returned objects should be in.

      This in turn made me realise that multiple inheritance could, with a little caution, even apply to the object's data. Just call both constructors and merge the resulting anonymous arrays. Problems will arise when the inherited classes use the same hash-entries for different purposes or when different types of variables are used, of course. At the end, one just reblesses the anonymous hash.

      Jeroen
      "We are not alone"(FZ)

        *shudders at the thoughts of his objects doing the can('can')*

        ------
        We are the carpenters and bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://114771]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-16 20:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found