2011-03-02 27 views
1

在類的構造方法我讀代碼片段如下圖所示:定義在Perl

sub new { 
     my $pkg = shift; 
     my $args = shift; 

     my @keys = keys %$args; 

     my $self = bless \%{$args}, $pkg; 
     $self->{'__properties'} = \@keys; 

     my $class = ref($self); 

     foreach my $meth (@keys) { 

       if (! $self->can($meth)) { 

         no strict "refs"; 

         *{ $class . "::" . $meth } = sub { 
           my $instance = shift; 
           return $instance->{$meth}; 
         }; 
       } 
     } 

     return $self; 
} 

的foreach循環,似乎它根據參數創建的一些方法。有兩行我不明白。有人可以幫我嗎?什麼是*{}用於?

no strict "refs"; 
*{ $class . "::" . $meth } 

最好的問候,

回答

0

正如eugene y已經解釋的那樣,這些行操縱符號表。在實踐中,他們爲了在類中創建只讀訪問方法,不管以何種屬性的任意名單獲得通過到構造這樣做:

#!/usr/bin/env perl 

use strict; 
use warnings; 
use 5.10.0; 

package SomeClass; 

sub new { 
    my $pkg = shift; 
    my $args = shift; 

    my @keys = keys %$args; 

    my $self = bless \%{$args}, $pkg; 
    $self->{'__properties'} = \@keys; 

    my $class = ref($self); 

    foreach my $meth (@keys) { 

     if (!$self->can($meth)) { 

      no strict "refs"; 

      *{$class . "::" . $meth} = sub { 
       my $instance = shift; 
       return $instance->{$meth}; 
      };   
     }  
    } 

    return $self; 
} 

package main; 

my $foo = SomeClass->new({foo => 5}); # Creates SomeClass::foo 

say $foo->foo; # 5 

my $bar = SomeClass->new({foo => 3, bar => 7}); # Creates SomeClass::bar 

say $bar->foo; # 3 
say $bar->bar; # 7 
say $foo->bar; # undef - ::bar was added to all instances of SomeClass 

say $foo->baz; # Boom! No such method. 

就個人而言,我覺得這是值得商榷的OO實踐(一類通常應該有一組已知的屬性,而不是每次構建實例時都添加新的屬性),但這就是它的作用...

1

這將創建一個符號表別名。
右側包含對函數的引用,所以Perl將它與包中的子例程$meth相混淆。

參見perlmod中的Symbol Tables