如何在创建对象时初始化特定的类变量?
问题描述:
到目前为止,我总是依赖于一个类中变量的顺序,但现在我试图以一种混洗顺序初始化这些变量。如何在创建对象时初始化特定的类变量?
例如,这是我通常在创建对象时执行的操作。
my $person1 = Person->new ('Fernando', 'Alonso', 36);
这就是我想要的目的。
my $person2 = Person->new (Age => 36, FistName => 'Fernando', LastName => 'Alonso');
我试图=>
参考几个文件(例如perldoc)我看到了,但他们没有一个完整的例子还给我。但是我实际上并没有在下面的脚本中工作,这是一个公平的MCVE,带有'cliché'包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, '', '');
输出如下。
First name : Fernando
Last name : Alonso
Age : 36
First name : Age
Last name : 36
Age :
那么,我应该如何创建对象来对类变量进行显式赋值?如有必要,我应该如何修改包裹Person
?
P.S.我避免在创建对象后更改变量。
答
原始Person
类构造函数需要参数以特定顺序包含值,但您希望指定键值对。通过将输入表示为散列引用,这很容易。
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;
}
如果要限制可以设置为FirstName
,LastName
,并且Age
键,你可以做这样的事情。
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;
}
以及进一步的增强,你可以提供其中主叫方未指定所有预期键
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;
}
的默认值...如果你想成为对错别字,你可以'删除$弹性args {$ key}'每个参数,这样你就可以事后检查未使用的参数,比如'if(my @unknown = sort keys%args){croak“Unknown named arguments:@unknown”; }' – amon
我尝试了两种解决方案,并且都完美地工作。 – ahmedus
'my $ self = {@_}'打破抽象。我认为你至少应该把它标为不合要求。 – Borodin