我有一个父包和一些子孙套餐:
#parent
package Mother;
sub new {
my ($class, $args) = @_;
my $self = bless {}, $class;
return $self;
}
# load sub...
sub getGrandchildren {
my ($self, $package) = @_;
# find all grandchildren dynamicly
my @grandchildren = ('Mother::Child::Grandchild');
# load all found packages and load their config
foreach my $grandchild (@grandchildren) {
# require etc
# load config
my $c = $grandchild->getConfig();
# damn ... $c is undef
# I expected { x => 2 } from grandchild
warn Dumper $c;
$config{$grandchild} = $c;
}
}
# this subroutine should be used
# by children and grandchildren
sub getConfig {
my ($self) = @_;
use no strict 'refs';
return ${$self::."config"};
}
1;
# child
package Mother::Child;
use parent qw/Mother/;
our $config = { x => 1 };
sub new {
my ($class, $args) = @_;
my $self = $class->SUPER::new($args);
$self->getGrandchildren(__FILE__);
return $self;
}
1;
# grandchild
package Mother::Child::Grandchild;
use parent qw/Mother::Child/;
our $config = { x => 2 };
sub new {
my ($class, $args) = @_;
my $self = $class->SUPER::new($args);
return $self;
}
1;
如果我打电话给这样的话:
my $child = Mother::Child->new();
所有的孙子都被装上了,应该装上他们的配件。
我试图通过一个子程序“getConfig()”来实现这一点,该子程序只在父级中定义。
问题是用
加载配置$grandchild->getConfig();
返回undef。
我想避免在每个子孙中创建一个子程序getConfig()来返回正确的配置(来自子或孙)。
是否可以使用此子/孙结构执行此操作?或者我做错了什么?
解决方案
正如@bvr所建议的,我用$ {$ self。“:: config”}替换了getConfig中的返回值,并添加了“no strict'refs'”。
答案 0 :(得分:1)
您的代码存在一些问题:
Mother::Child
的构造函数未返回$self
,因此您无法从Mother::Child::Grandchild->new
调用中获得正确的引用。 $self::config
是访问包变量的正确语法。你需要这样的东西:
sub getConfig {
my ($self) = @_;
my $class = ref $self;
no strict 'refs';
return ${$class . "::config"};
}
getGrandchildren
错误配置 - 例如,您获得变量@grandchildren
。
编辑:将no strict 'refs'
添加到getConfig
子例程,以便在本地停用此检查。