【发布时间】:2017-09-17 04:10:26
【问题描述】:
我正在使用 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
}
}
而这个(通过$a->generate在外部调用generate sub)不会:
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: {}
}
程序返回错误:
无法在 base2.pl 行的未定义值上调用方法“Siberian” 39.
【问题讨论】:
-
因为当您调用 $a->generate 时,您将此属性添加到 Cat 类,而不是此类 Cat ($a) 的实例。即使您添加到实例(对象),该字段也不会被初始化。
标签: perl oop code-generation moose