如何在创建对象时初始化特定的类变量?

问题描述:

到目前为止,我总是依赖于一个类中变量的顺序,但现在我试图以一种混洗顺序初始化这些变量。如何在创建对象时初始化特定的类变量?

例如,这是我通常在创建对象时执行的操作。

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; 
} 

如果要限制可以设置为FirstNameLastName,并且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; 
} 
+3

的默认值...如果你想成为对错别字,你可以'删除$弹性args {$ key}'每个参数,这样你就可以事后检查未使用的参数,比如'if(my @unknown = sort keys%args){croak“Unknown named arguments:@unknown”; }' – amon

+0

我尝试了两种解决方案,并且都完美地工作。 – ahmedus

+0

'my $ self = {@_}'打破抽象。我认为你至少应该把它标为不合要求。 – Borodin