http://www.perlmonks.org?node_id=999792

puneet.keswani has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I have a very basic doubt, but its troubling me, I was reading OOP in Perl and saw that at all the instances inside the subroutene new, which is called a constructor, we make use of anonymous hash, whats the reason, why do we do that, why cant we make a named hash and use use the reference to that named hash.

Thanks in advance !!

Replies are listed 'Best First'.
Re: Anonymous Hash in Constructor
by tobyink (Canon) on Oct 18, 2012 at 18:56 UTC

    You can. It works either way.

    use v5.10; use strict; use warnings; { package Local::Test; sub new1 { my $class = shift; bless {} => $class; } sub new2 { my $class = shift; my %hash = (); bless \%hash => $class; } sub does_it_work { say "yes, it works"; } } my $obj1 = Local::Test->new1; $obj1->does_it_work; my $obj2 = Local::Test->new2; $obj2->does_it_work;

    And there's no rule that the blessed reference has to be a hashref; it can be any kind of reference. Hashrefs are usually the most convenient, but there are sometimes advantages to other structures. Arrayrefs tend to perform slightly better, though your object's internal structure is rarely the bottleneck in real life applications. If your object represents something file-like, then a blessed filehandle may be convenient. The URI package uses blessed references to scalar strings.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      I somehow find it instructive to do this…

      { package SomeClass; sub new1 { bless {} } sub new2 { bless \%hash } sub does_it_work { print "Yes, it works\n" } } $obj1 = SomeClass->new1; $obj1->does_it_work; $obj2 = SomeClass->new2; $obj2->does_it_work;

      …to your fine example. Removing all pragmas is intentional. This isn't quality code. It's simple code to make the rudiments of something clearer—to me, at least. I learned something by this reduction.

        Ah, but using strict and warnings demonstrates that nothing in the example is considered bizarro stuff that Perl will complain about.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Anonymous Hash in Constructor
by AnomalousMonk (Archbishop) on Oct 18, 2012 at 19:54 UTC
    ... we make use of anonymous hash, whats the reason, why do we do that ...

    tobyink has already pointed out and demonstrated that is is quite possible to create a named hash and then bless and return a reference to the hash as the object reference. But why is this not commonly done? The name of the referenced hash (or any other named data structure that might be used) is lost as soon as the constructor subroutine ends, and there is no way to ever access object data again except by reference, so there seems to be no point. The only reason I can think of to create and reference a named hash (or whatever structure) is self-documentation: a hash named  %attributes pretty much says it all, but one can do the same for an anonymous reference.

      Of course, a local-variable is “lost” too, as soon as the containing subroutine (the constructor ...) ends.   So in this case, it really is a matter of personal preference on the part of the author.   You’re going to create something, you might or might not twiddle with it, you’re going to bless it, and then you’re going to return it as the function-result.   Q.E.D.   As long as the meaning of the block of code which you use to do that is abundantly obvious, and effortlessly maintainable, “Feel Free.™”

        Indeed. The two sample constructors I provided are functionally identical. If the Perl compiler were smart enough, it could happily generate the same optree from each (but it currently does not).

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Anonymous Hash in Constructor
by sundialsvc4 (Abbot) on Oct 18, 2012 at 19:44 UTC

    Indeed, I prefer to define a local variable in my constructor, to use that to initialize the structure as need-be, bless it, and then return it.   It’s simply that particular author’s habit or perhaps meant in the name of editorial clarity.

    The single most-important idea that “you really need to grok, and grok thoroughly,” is that all-important notion of what bless actually does.

Re: Anonymous Hash in Constructor
by jmlynesjr (Deacon) on Oct 19, 2012 at 01:14 UTC

    Wouldn't an anonymous hash provide for/enforce encapsulation, a basic OOP concept?

    James

    Update2:

    Thanks for the explanation. As always, I have more reading to do! My thought was that naming the hash would create a symbol table entry that would allow direct access from the outside, not that you would want to or should do that.

        Which, of course, would not make sense to do.   The constructor’s purpose is to return a new unique instance of a blessed object as its return value.   So, the only “debate” here is whether, within the body of that constructor, the hash that is to be returned is specified anonymously or not.   And, it makes utterly no difference one way or the other to Perl.

Re: Anonymous Hash in Constructor
by Jenda (Abbot) on Oct 19, 2012 at 21:25 UTC

    And why for gawd's sake don't you TRY to use a named hash and use the reference to that named hash?!? Is that so hard? Do you plan to run here and wait for an answer to a question you could answer yourself by writing five lines of code and seeing what happens? Do you actually plan to become a programmer or are you just trying to pass a test preferably with zero effort on your side and with no understanding of the subject?

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.