2017-04-20 41 views
3

我使用Moose :: Meta :: Class動態添加類,方法和屬性。爲什麼相同的函數調用會在對象內部帶來不同的結果?

有人可以解釋爲什麼這代碼工作(內部調用generate()子程序,裏面Cat類):

輸出的
package Cat; 

use Moose; 

sub generate { 

    my $siberian = Moose::Meta::Class->create('Siberian'); 
    $siberian->add_method(echo => sub { print "yeah!\n" }); 


    my $tiger = Moose::Meta::Class->create('Tiger'); 
    $tiger->add_attribute(
     Siberian => { 
      is  => 'ro', 
      default => sub { $siberian->new_object; } 
     }, 
    ); 

    __PACKAGE__->meta->add_attribute(
     Tiger => { 
      is  => 'ro', 
      default => sub { $tiger->new_object }, 
     }, 
    ); 

    print "Generation done!\n"; 
} 

generate(); 


package main; 

use Data::Printer; 

my $a = Cat->new; 

# $a->generate; 
p($a); 
$a->Tiger->Siberian->echo; # returns 'yeah!' 

p($a)

Cat { 
    Parents  Moose::Object 
    public methods (3) : generate, meta, Tiger 
    private methods (0) 
    internals: { 
     Tiger Tiger 
    } 
} 

而這一次(外部調用generate子,通過$a->generate)沒有:

package Cat; 
use Moose; 

sub generate { 

    my $siberian = Moose::Meta::Class->create('Siberian'); 
    $siberian->add_method(
     echo => sub { print "yeah!\n" } 
    ); 

    my $tiger = Moose::Meta::Class->create('Tiger'); 
    $tiger->add_attribute(
     Siberian => { 
      is  => 'ro', 
      default => sub { $siberian->new_object; } 
     }, 
    ); 

    __PACKAGE__->meta->add_attribute(
     Tiger => { 
      is  => 'ro', 
      default => sub { $tiger->new_object }, 
     }, 
    ); 

    print "Generation done!\n"; 

} 

# generate(); 


package main; 
use Data::Printer; 

my $a = Cat->new; 
$a->generate; 
p($a); 
$a->Tiger->Siberian->echo; # returns 'yeah!' 

輸出的p($a)

Cat { 
    Parents  Moose::Object 
    public methods (3) : generate, meta, Tiger 
    private methods (0) 
    internals: {} 
} 

和程序返回一個錯誤:

Can't call method "Siberian" on an undefined value at base2.pl line 39.

+0

因爲當你調用$ a-> generate時,你將這個屬性添加到類Cat中,而不是添加到這個類Cat($ a)的實例中。即使你添加到實例(對象),該字段將不會被初始化。 –

回答

0

由於generate不反對,但類方法,它的需要new之前調用它:

Cat->generate; 
my $a = Cat->new; 
相關問題