p_agarwal p_agarwal - 1 month ago 13
Perl Question

How do I resolve one argument passed to a subroutine defined to accept 2 parameters in Perl

I am creating a new object as follows:

my $new_obj = new P_module({key => 'abc'});


The P_module has a constructor defined as follows:

sub new {
my ($pkg, $input) = @_;
my $obj = {};
bless ($obj, ref($pkg)||$pkg);
$obj->{key} = $input->{key};
}


From what I have read, since a hash is being passed as argument to new, it will be represented as a 2-element array. So,
pkg
should be
key
and
input
should be
abc
. Then, how does
obj
come to hold a key
key
and what does
$input->{key}
even mean?

Answer Source

First of all,

my $new_obj = new P_module({ key => 'abc' });

is better written as

my $new_obj = P_module->new({ key => 'abc' });

This is short for

my %anon = ( key => 'abc' );
my $new_obj = P_module->new(\%anon);

When making a method call, the invocant (what's left of the ->) is passed as the first argument. That means $pkg is the string P_module, and $input is the reference returned by { key => 'abc' }.

Since $input is a reference to a hash, $input->{key} gets the value of the element with key key from the referenced hash.


How I would have written this:

sub new {
    my ($class, %args) = @_;
    my $self = bless({}, $class);      # If base class.
    #my $self = $class->SUPER::new();  # If inheriting.
    $self->{key} = $args{$key};
    return $self;
 }

 my $obj = P_module->new( key => 'abc' );

There's no need for a hash in the caller, and there's no reason to support $existing_obj->new. It also uses more standard names $class and $self.