2017-09-14 14 views
1

を2つのパラメータを受け入れるように定義されたサブルーチンに渡さは、次のように私は新しいオブジェクトを作成していたPerl

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

私が読んだところでは、ハッシュがnewに引数として渡されているので、2要素配列として表されます。したがって、pkgkeyであり、inputabcである必要があります。次に、のキーを保持するにはどうすればとなり、$input->{key}はどういう意味ですか?

答えて

6

まず、

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

が良い

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

として書かれているこれは

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

の略です

メソッド呼び出しを行うときに、invocant(->の左にあるもの)が最初の引数として渡されます。つまり、$pkgは文字列P_moduleであり、$input{ key => 'abc' }によって返された参照文字列です。

$inputがハッシュへの参照であるため、は、参照されたハッシュからキーkeyを持つ要素の値を取得します。

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'); 

呼び出し側でハッシュのための必要はありません、と$existing_obj->newをサポートする理由はありません:私はこれを書いているだろうどのように


。また、より標準的な名前$class$selfも使用しています。これに代えて

bless ($obj, ref($pkg)||$pkg); 

+0

ありがとうございます。それは非常に有用な説明でした:) –

0

周囲の中括弧は、参照または単一のスカラーであるhashrefを作成します。引数の値は、供給されたハッシュコード$input->{key}キー"key"に関連付けられた値にアクセスする

から"P_module"

  • $input —参照おそらく、

    • $pkg —含むパッケージの名前になります発呼者によって供給されるもの

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

      それはあなたが

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

      "key"に関連付けられた値が

      でオブジェクト’の状態にコピーされますよう、別のキーが追加される場合があります

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

      としてこれを書くためのより良いスタイルと考えられています

      $obj->{key} = $input->{key}; 
      

      Perlサブルーチンは最後の式の値を返しますので、あなたのcod eにバグがあります。あなたはそれがその後、他のメソッドを呼び出すために使用することができますblessされたオブジェクトを返しますのでP_module::newの最後の行が

      bless ($obj, ref($pkg)||$pkg); 
      

      になりたい、例えば

      my $new_obj = new P_module({key => 'abc'}); 
      print $new_obj->other_method_that_you_must_define(), "\n"; 
      
  • +0

    私はそれを考慮しませんでした。私は説明できないコードだけを掲載しました。しかし、エラーを指摘してくれてありがとう。 –

    2

    はあなたがこれを持っている理由がありますか?

    bless ($obj, $pkg); 
    

    れていない場合、私はあなたがどこか他のコードからそれを貼り付け&を切ると仮定しています。おそらくあなたが望むのは後者です。あなたはおそらくその後、ちょうど

    bless ($obj, $pkg); 
    
    +1

    私は同意します。もしあなたが '$ existing_obj-> new'を必要とするような場合には、' ref($ existing_obj) - > new'を使用することができます。これと(クローンが必要な場合は別の 'クローン'コンストラクタ)は、私が心配している限りはるかにクリーンです。つまり、この答えは本当にコメントであり、私はそれをそのようにマークします。 – ikegami

    +1

    コメントシステムで詳細な説明に必要なスペースと書式が許可されていれば、コメントしたでしょう。 –

    0

    に固執、それを行う必要はありませんので

    my $new_object = $existing_obj->new; 
    

    代わりの

    my $new_object = new Classname; 
    

    ref($pkg)||$pkgはあなたがこれを行うことができること

    メソッドを呼び出すと、オブジェクト自体がシーンの裏に渡されます。サブクラスがblessを使用する場合は、コンストラクタであり、代わりにクラス名が渡されます。したがって、どのメソッドも、オブジェクトまたはクラス名を最初の引数として受け取ることになります。残りはメソッドに明示的に渡される引数です。

    あなたはハッシュリファレンス{...}、スカラは何かを渡します。したがって、 "quitely"というクラス名が$pkgに割り当てられている場合は、$inputに割り当てられます。

    ハッシュ参照して、そのインターフェイスのコンストラクタは、最も通例単に最後に評価文のリターンが返されるのでreturnを省略してもよい

    sub new { 
        my ($class, $input) = @_; 
        my $self = { %$input }; 
        return bless $self, $class; 
    } 
    

    として書き込まれます。最後の2行は単にreturn bless { %$input }, $class;と書くことができ、(匿名の)ハッシュリファレンスは初期化され、パッケージ$classに祝福され(オブジェクトなので)返されます。

    しかし、通常は引数を処理する必要があります。 1つは、である必要があります。クラスがサポートしているものに準拠していることを確認し、ユーザが渡したキーを属性に盲目的に割り当てるだけではありません。必要に応じて値を確認するなどしてデフォルト値を設定します。

    このデータの初期化は、別のサブルーチンに分割されることがあります。new$selfが更新されるように、コードが参照を介して、「バック」を書き込む例えば

    sub new { 
        my ($class, $input) = @_; 
        my $self = {}; 
        bless $self, $class;  # $self is an object now 
        $self->_init($input);  # on which methods can be called 
        return $self; 
    } 
    
    sub _init { 
        my ($self, $args) = @_; 
        # Check arguments, work out defaults (etc), 
        # then assign to self as appropriate 
        %$self = %$args; 
    } 
    

    これは "通常の" 呼び出しに

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

    として使用されず間接表記new P_moduleされるべきです。慣習的にnewと呼ばれるコンストラクタは、blessハッシュリファレンス(オブジェクトの代わりにクラス名が渡される)がそのパッケージを "認識"してオブジェクトであるため、通常のサブスペシャルです。

    文章:perlmod(クラスはパッケージです)、チュートリアルperlootut、および参照perlobjです。

    Perlに組み込まれたオブジェクト指向の機能に慣れたら、私がやることをお勧めします。このすべてを(そしてはるかに)簡単にするモジュールがたくさんあります。

    最初にお勧めするのは、非常に現代的なMooseとその軽量対応品Mooです。

    +0

    'my $ self = my $ self = {%$ input}; – ikegami

    +0

    @ikegami私は、よりコンパクトな方法(私は正確に型付けされた正確な形式を持っていた)を表示することから取り戻しました。これの基本的な目的。しかし、それは魅力的です...加えられました。編集していただきありがとうございます。 – zdim

    関連する問題