2017-10-16 5 views
1

これまで私は常にクラスの変数の順序に頼っていましたが、今はそれらの変数をシャッフルされた順序で初期化しようとしています。オブジェクトの作成中に特定のクラス変数を初期化する方法はありますか?

たとえば、これは私が通常オブジェクトを作成するときに行うことです。

my $person1 = Person->new ('Fernando', 'Alonso', 36); 

これは私が達成しようとしているものです。

my $person2 = Person->new (Age => 36, FistName => 'Fernando', LastName => 'Alonso'); 

私は私が見たが、彼らは私に完全な例を返しませんでしたいくつかの文書(例えばperldoc)に係る=>を試してみました。しかし、私は実際に次のスクリプトで作業していません。それは 'cliché'パッケージPersonを持つ公正なMCVEです。

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.オブジェクトの作成後に変数を変更することは避けてください。

答えて

5

元の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){croak" Unknown named arguments:@unknown "のような未使用のargsをチェックすることができるように、' args {$ key} '' } ' – amon

+0

私は両方のソリューションを試して、どちらも完璧に動作しました。 – ahmedus

+0

'my $ self = {@_}'は抽象を破ります。私はあなたが少なくともそれが望ましくないとマークするべきだと思います。 – Borodin

関連する問題