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

Hi all,

I have just started learning perl and OOPs concepts. I have a query regarding perl OOP concept.

Below is a standard piece of code showing class implementation. I understand with limited knowledge that $self is a reference to a hash, and this hash gets converted to an object after getting blessed. Blessing essentially means that the $self hash can now use any function in XYZ class for manipulation. Please correct me if I am wrong anywhere.

I have mostly come across examples where constructor function, such as "new" here contains a hash that gets blessed within the constructor. Many a times this hash may be nested to form a complex data structure. However, suppose instead of having one complex hash structures I choose to have two simple hash structures (say $self1 and $self2) . My question is, can we have two hashes (say $self1 and $self2) and both being blessed with the same class within the constructor. Is this allowed? If yes, then do $self1 and $self2 form two separate objects after being blessed. How then are $self1 and $self2 connected/related in anayway? Also, what are advantages of having a complex single hash vis a vis two simple hashes? I am actually confused. I guess I am missing something here.

Please advise.

Thanks,

package XYZ; sub new { my $class = shift; my $self = {}; return bless $self, $class; }

Replies are listed 'Best First'.
Re: Perl OOP
by jdporter (Paladin) on Oct 11, 2004 at 14:07 UTC
    Blessing essentially means that the $self hash can now use any function in XYZ class for manipulation.
    Close enough.
    My question is, can we have two hashes (say $self1 and $self2) and both being blessed with the same class within the constructor?
    Sure we can — this is Perl — but you'd have to be careful lest you drop one on the floor. To wit...
    do $self1 and $self2 form two separate objects after being blessed?
    Yes. Quite.
    How then are $self1 and $self2 connected/related in any way?
    Perl doesn't connect them internally in any way; they're unrelated except for being blessed into the same class. If you want them connected, you could do it yourself. For example, you could have data members in each hash which are references to the other...
    $self1->{'other'} = $self2; $self2->{'other'} = $self1;
    Or you could store them in some container...
    push @all_your_Base, $self1, $self2;
    I think the important point here is that if you have two (or more) blessed objects of a given class, they must all have internal data structures that work with the methods of the class. But if the different objects are meant to have different behaviors, then by Jah you'd better make them different classes. That's why Jah gave us the ability to make different classes. :-)

      you could have data members in each hash which are references to the other

      Careful with this one. You'll want to weaken the references (with Scalar::Util::weaken() or some such) so that Perl's refcounting GC doesn't trip over it.

      "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Re: Perl OOP
by BrowserUk (Patriarch) on Oct 11, 2004 at 14:13 UTC

    Two alternatives to the hash of hashes way come to mind.

    Use an anonymous array ref as your object, and store your two hashes inside that:

    package XYZ; use constant { HASH1 => 0, HASH2 => 1, } sub new { my $class = shift; my $self = [ { something => 'this' }, { something_else => 'that' } ]; return bless $self, $class; } sub method { my $self = shift; print $self->[ HASH1 ]{ something }, $self->[ HASH2 ]{ something_els +e }; }

    Use Abigail's Inside-out object technique:

    package XYZ; my( %instances ); sub new { my $class = shift; my $self = bless \$class, $class; $instances{ $self }{ hash1 } = { something => 'this' }; $instances{ $self }{ hash2 } = { something_else => 'that' }; return $self; } sub method { my $self = shift; my( $hash1Ref, $hash2Ref ) = @instances{ $self }{ hash1, hash2 }; print $hashRef1->{ something }, $hashRef2->{ something_else }; }

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: Perl OOP
by pelagic (Priest) on Oct 11, 2004 at 15:00 UTC
    I would like to recommend you reading the tutorial perlboot written by merlyn.
    I thinks it's a easy way to start with OO and Perl.

    pelagic
Re: Perl OOP
by gmpassos (Priest) on Oct 11, 2004 at 22:15 UTC
    What can make you to understand better is to know the meaning of the code {}.

    {} means a reference to an anonoymous HASH. Is the same thing of the code above, but without give a name to the hash:

    # this... my $self = {} ; # ... is the same of: my %foo ; my $self = \%foo ;
    Other thing that you should know is that each time that you make \%foo or {} we will point to a new HASH. So, each time that we go inside the sub new(), a new %foo will be created (since %foo is local due my). Or each time that we execute {} we have a reference to a new anonymous HASH. We can see that above:
    my @hold_ref ; for(1..3) { my $hash_ref = {} ; push(@hold_ref , $hash_ref) ; print "$hash_ref\n" ; }
    Output:
    HASH(0x1a7f10c) HASH(0x1a7f130) HASH(0x1a75468)
    Note that the array @hold_ref is just to ensure that we won't have new HASHES created in the same address of old hashes already cleanned from the memory.

    So, bless() will always bless a new reference, what means that we have a new object (well this is why we call by the name new() or create()). The meaning of bless is to say that some reference belong to a package/class, and with that we can do a lot of things, and one of them is to call a method, that is the basic of Object Orientation.

    Other question is "Why Perl does OO with a reference to some data structure that belongs to a package?". Well, the main purpose of OO is to have a data structure related to the methods that will interact/change this data. Well, actually OO borned in this way, but they forgot to tell this to us.

    Graciliano M. P.
    "Creativity is the expression of the liberty".

Re: Perl OOP
by SpanishInquisition (Pilgrim) on Oct 11, 2004 at 20:02 UTC
    A few basic things to remember.

    (1) In Perl, bless is something sort of magical. New is just a function you create. So it could just be named "Defroobniculate". "new" is preferred of course, but whatever it does is essentially legal. Your packages technically don't have to return an object at all.

    (2) Creating multiple blessed objects inside of new is perfectly legal, but I want to ask "why" here, as to why you are returning more than one. If you are constructing an object tree, for instance, usually you would expect the return of the root node. What you are doing is totally legal and valid, I'm just curious... I haven't needed a "new_dog_and_cat" function before -- though perhaps I could see a return of a list of objects (or a hash of objects) being useful. (I just want to find an example where that would be the case)

Re: Perl OOP
by newbio (Beadle) on Oct 12, 2004 at 06:09 UTC
    Wow, this forum rocks! Thank you Guys! It really helps. Most importantly, it keeps my interest in Perl alive. This way, a biologist like me is sure to learn a bit of Perl....:) Take care!