父/子结构中的变量/子程序继承

时间:2012-02-13 14:04:50

标签: perl inheritance parent-child

我有一个父包和一些子孙套餐:

#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'”。

1 个答案:

答案 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子例程,以便在本地停用此检查。