Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do object oriented concept works in Perl

Tags:

oop

perl

I am reading a book on perl and so far I understand the concept of OOP until i encountered this code:

sub new {
    my $invocant = shift;
    my $class   = ref($invocant) || $invocant;
    my $self = {
        color  => "bay",
        legs   => 4,
        owner  => undef,
        @_,                 # Override previous attributes
    };
    return bless $self, $class;
}
$ed       = Horse->new;                    # A 4-legged bay horse
$stallion = Horse->new(color => "black");  # A 4-legged black horse

What I see in that code is that whatever is passed in the new subroutine is considered as the package name which will be converted into an object reference with this code:

my $invocant = shift; #this one just get the name of the package which is the argument passed

return bless $self, $class;

  1. Now what is the use of the pre-declaration of the hash (not empty hash)? and why is the @_ supplied in the last part of the list? what for?

Next is this statement based on that code above:

This Horse constructor ignores its invocant's existing attributes when used as an instance method. You could create a second constructor designed to be called as an instance method, and if designed properly, you could use the values from the invoking object as defaults for the new one:

which 90% of that statement I dont understand.

  1. What is an instance method? or object method? can you provide an example?

I know that this one my $class = ref($invocant) || $invocant; are object and instance methods but Im not sure how they differ or how to use them differently.

The "second constructor" mentioned above is this:

$steed  = Horse->new(color => "dun");
$foal   = $steed->clone(owner => "EquuGen Guild, Ltd.");
sub clone {
    my $model = shift;
    my $self  = $model->new(%$model, @_);
    return $self;     # Previously blessed by ->new
}

Which again, I have no idea what it does. So anyone can clarify this for me.

like image 635
Belmark Caday Avatar asked Jan 20 '26 18:01

Belmark Caday


1 Answers

Now what is the use of the pre-declaration of the hash (not empty hash)? and why is the @_ supplied in the last part of the list? what for?

This is a very clever approach which lets you achieve 2 things at once:

  1. Allow you to have default values for the constructor

  2. Allow you to override some (or all) of those defaults with a has passed in to the constructor call.


How does this work? Based on 3 things you need to know about hashes:

  • A hash can be treated as a list, by flattening out into a "key1", "value1", "key2", "value2" ... list. This happens if you pass a hash as a parameter to a subroutine: mySub(%hash1)

  • A list (with even # of elements) can be turned INTO a hash via a reverse process.

  • A hash, constructed from a list, where a certain key is encountered more than once, will ONLY have that key once, and - important here - the value of that key in the resulting hash will be the LAST instance among values associated with that key.

In other words, the following 4 assignments produce the same exact resulting data structure:


    my %hash1;
    $hash1{20} = 2;
    $hash1{40} = 4;

    my %hash2 = ( 20, 2, 40, 4); # Notice that "," is same as "=>"

    my %hash3 = ( 20 => 2, 40 => 4); # Notice that "," is same as "=>"

    my %hash4 = ( 40 => 1, 40 => 3, 20 => 2, 40 => 4); 
    # first 2 couples will be effectively ignored, due to same keys later on

Example:

  • If you pass in a hash that has no color key but legs: Horse->new(legs=>3)

    • @_ array will contain 2 elements, "legs" and "3" (obtained by flattening that hash).

    • Your new hash - to be assigned to $self - will then be constructed from the following list:

       ("color","bay", 
       "legs", "4", # Will get overwritten
       # more 
       "legs", "3")
      
    • Now, as per the third bullet above, "legs","4" pair is overwritten by later "legs","3" in a hash assignment; so the resulting hash will have a (default) value of "bay" for the color, and a passed-via-constructor-arguments value of "3" for legs.

like image 56
DVK Avatar answered Jan 23 '26 06:01

DVK