根据您的编辑,$A 和 $B 将用于调用方法。
所以,我假设它们是作为基类的类数据存储的单例对象。
如果将它们作为变量公开,它们很容易被更改,并且可能会出现各种问题。
为什么不使用访问器?
package Foo::Proto;
my $A;
my $B;
sub A {
return $A;
}
sub B {
return $B;
}
package Foo::Child;
our @ISA= qw(Foo::Prototype);
sub test {
my $self = shift;
$self->A->blah();
# Or if I am doing many things with A, and want to type less:
my $A = $self->A;
$A->blah();
}
package Foo::Kid;
our @ISA= qw(Foo::Prototype);
# If you will never change $A in the prototype, you could do this:
my $A = __PACKAGE__->A;
sub test {
$A->blah();
}
但这一切似乎都在胡闹。
为了在我的代码中解决这个问题,我会使用 Moose,然后创建一个角色来引入 A 和 B 相关的方法。
my $m = Foo::Mooseling->new();
$m->test_A();
$m->test_B();
BEGIN { # This is going to be $A, I needed something to call $A->foo on.
package Thing1;
sub new { bless {}, __PACKAGE__; }
sub foo { print __PACKAGE__."::foo()\n"; }
sub blah { print __PACKAGE__."::blah()\n"; }
}
BEGIN { # This is going to be B. It is not interesting either.
package Thing2;
sub new { bless {}, __PACKAGE__; }
sub bar { print __PACKAGE__."::bar()\n"; }
sub bluh { print __PACKAGE__."::bluh()\n"; }
}
# This is the interesting part:
BEGIN { # This ROLE will provide A and B methods to any objects that include it.
package Foo::ProtoMoose;
use Moose::Role;
has 'A' => (
is => 'ro',
isa => 'Thing1',
handles => [qw( foo blah )], # Delegate calls to foo and blah for consuming object to this A.
default => sub { Thing1->new(); }, # Create a Thing1 to be A.
);
has 'B' => (
is => 'ro',
isa => 'Thing2',
handles => [qw( bar bluh )],
default => sub { Thing2->new(); },
);
}
BEGIN { # This method consumes the ProtoMoose Role.
package Foo::Mooseling;
use Moose;
with 'Foo::ProtoMoose';
sub test_A {
my $class = shift;
$class->foo;
$class->blah;
}
sub test_B {
my $class = shift;
$class->bar;
$class->bluh;
}
}
如果您希望 Thing1 和 Thing2 成为单例,请使用 MooseX::Singleton。