Reputation:
So far I always relied on the order of variables in a class, but now I'm trying to initialize those variables in a shuffled order.
For example, this is what I normally do while creating an object.
my $person1 = Person->new ('Fernando', 'Alonso', 36);
And this is what I'm trying to achieve.
my $person2 = Person->new (Age => 36, FistName => 'Fernando', LastName => 'Alonso');
I tried =>
regarding to several documents (e.g. perldoc) I saw, but they didn't return a complete example to me. However I don't actually work on the following script, it's a fair MCVE with the 'cliché' package Person
.
use strict;
use warnings;
package Person;
sub new {
my $class = shift;
my $self = {
FirstName => shift,
LastName => shift,
Age => shift,
};
print "First name : $self->{FirstName}\n";
print "Last name : $self->{LastName}\n";
print "Age : $self->{Age}\n\n";
bless $self, $class;
return $self;
}
# Works well
my $person1 = Person->new ('Fernando', 'Alonso', 36);
# (?) How to assign 36 directly to $self->{Age}
my $person2 = Person->new (Age => 36, '', '');
The output is as follows.
First name : Fernando
Last name : Alonso
Age : 36
First name : Age
Last name : 36
Age :
So, how should I create the object to make explicit assignments to the class variables? If necessary, how should I modify package Person
?
P.S. I avoid changing the variables after the object is created.
Upvotes: 1
Views: 175
Reputation: 118605
The original Person
class constructor expects the arguments to contain values in a specific order, but you want to specify key-value pairs. This is easy enough by representing the input as a hash reference.
package Person;
sub new {
my $class = shift;
# read @_ as list of key-value pairs;
# set $self as reference to hash of these pairs
my $self = { @_ };
#my $self = { my %args = @_ }; # if you like your abstractions unbroken
bless $self, $class;
return $self;
}
If you want to restrict the keys that can be set to FirstName
, LastName
, and Age
, you could do something like this.
package Person;
sub new {
my $class = shift;
my %args = @_;
my $self = {
FirstName => $args{FirstName},
LastName => $args{LastName},
Age => $args{Age},
};
bless $self, $class;
return $self;
}
and as a further enhancement, you could provide default values where the caller has not specified all of the expected keys
package Person;
sub new {
my $class = shift;
my %args = @_;
my $self = {
FirstName => $args{FirstName} // "Fred",
LastName => $args{LastName} // "Flinstone",
Age => $args{Age} // 42,
};
bless $self, $class;
return $self;
}
Upvotes: 4