I'm a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot.
package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I don't get what this line does at all, but I always see it. Do I need it? my $type = shift; #I'm turning the array of inputs into a hash, called parameters. my %params = @_; #I'm making a new hash called $self to store my instance variables? my $self = {}; #I'm adding two values to the instance variables called "High" and "Low". #But I'm not sure how $params{'High'} has any meaning, since it was an #array, and I turned it into a hash. $self->{'High'} = $params{'High'}; $self->{'Low'} = $params{'Low'}; #Even though I read the page on [bless][2], I still don't get what it does. bless $self, $type; }
And another example is:
package Bar; sub new { my $type = shift; #I still don't see how I can just turn an array into a hash and expect things #to work out for me. my %params = @_; my $self = []; #Exactly where did params{'Left'} and params{'Right'} come from? $self->[0] = $params{'Left'}; $self->[1] = $params{'Right'}; #and again with the bless. bless $self, $type; }
And here is the script that uses these objects:
package main; $a = Foo->new( 'High' => 42, 'Low' => 11 ); print "High=$a->{'High'}\n"; print "Low=$a->{'Low'}\n"; $b = Bar->new( 'Left' => 78, 'Right' => 40 ); print "Left=$b->[0]\n"; print "Right=$b->[1]\n";
I've injected the questions/confusion that I've been having into the code as comments.
The constructor method is a Perl subroutine that returns an object which is an instance of the class. It is convention to name the constructor method 'new', but it can be any valid subroutine name. The constructor method works by using the bless function on a hash reference and the class name (the package name).
shift keyword takes the package name from the default array “@_” and pass it on to the bless function. bless function is used to return a reference which ultimately becomes an object. And in the end, the constructor will finally return the instance of the class Employee(here).
A constructor can be defined to use parameters (and thus require arguments) of any type - both class types and primitive types (int, float, char, etc..) If the constructor is called like new SomeClass(someObject) , someObject is the argument passed to the constructor of SomeClass.
Perl does not provide any special syntax for class definitions. A package is simply a namespace containing variables and subroutines. The only difference is that in a class, the subroutines may expect a reference to an object or the name of a class as the first argument.
To answer the main thrust of your question, since a hash can be initialized as a list of key => value
pairs, you can send such a list to a function and then assign @_
to a hash. This is the standard way of doing named parameters in Perl.
For example,
sub foo { my %stuff = @_; ... } foo( beer => 'good', vodka => 'great' );
This will result in %stuff
in subroutine foo
having a hash with two keys, beer
and vodka
, and the corresponding values.
Now, in OO Perl, there's some additional wrinkles. Whenever you use the arrow (->
) operator to call a method, whatever was on the left side of the arrow is stuck onto the beginning of the @_
array.
So if you say Foo->new( 1, 2, 3 )
;
Then inside your constructor, @_
will look like this: ( 'Foo', 1, 2, 3 )
.
So we use shift
, which without an argument operates on @_
implicitly, to get that first item out of @_
, and assign it to $type
. After that, @_
has just our name/value pairs left, and we can assign it directly to a hash for convenience.
We then use that $type
value for bless
. All bless
does is take a reference (in your first example a hash ref) and say "this reference is associated with a particular package." Alakazzam, you have an object.
Remember that $type
contains the string 'Foo', which is the name of our package. If you don't specify a second argument to bless
, it will use the name of the current package, which will also work in this example but will not work for inherited constructors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With