我只是想这样做:http://modernperlbooks.com/mt/2011/08/youre-already-using-dependency-injection.html。真的没有从示例代码中偏离太多。
这就是我所拥有的:
package M;
use Moose;
use Exporter;
use Data::Dumper;
sub new {
print "M::new!\n";
my $class = shift;
return bless {}, $class;
}
sub x {
my ($self, $stuff) = @_;
print Dumper($stuff);
}
#################################
package Foo;
use Moose;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = ();
has 'mS', is => 'ro', default => sub { M->new };
sub new {
my $class = shift;
return bless {}, $class;
}
sub bar {
my ($self, $data) = @_;
# do stuff here...
# ...
my $foo = $self->mS;
# this...
$foo->x($data);
# ...causes "Can't call method "x" on an undefined value at Foo.pm line 45."
}
1;
值得注意的是M::new!
消息永远不会出现,所以我猜它永远不会到达。发生了什么事?
答案 0 :(得分:2)
使用Moose,您不应该写sub new
。 Moose为您提供构造函数。
此外,使用Exporter对于面向对象的模块毫无意义。以下程序适合我:
#!/usr/bin/perl
{ package M;
use Moose;
use Data::Dumper;
sub x {
my ($self, $stuff) = @_;
print Dumper($stuff);
}
}
{ package Foo;
use Moose;
has mS => ( is => 'ro', default => sub { 'M'->new } );
sub bar {
my ($self, $data) = @_;
my $foo = $self->mS;
$foo->x($data);
}
}
my $foo = 'Foo'->new;
$foo->bar('test');
答案 1 :(得分:1)
您有一个解决方案 - 当您使用Moose时,请不要编写自己的new()
方法。但还有一点可能是值得的。
Moose将为您的Foo类提供的构造函数可以很好地替代new()
方法。但是,Moose为你的M班提供的那个将缺少一个功能 - 它不会打印你的" M :: new!\ n"信息。我们如何绕过那个?
在Moose中,您可以定义BUILD()
方法,该方法将在new()
返回新对象后立即调用。这是一个放置新对象所需的额外初始化的好地方。这也是您print()
电话的好地方(尽管在对象构建之后发生,而不是之前 - 因此它不是确切的替代品。)