Переменное / подпрограммное наследование в родительской / дочерней структуре - PullRequest
1 голос
/ 13 февраля 2012

У меня есть родительский пакет и несколько дочерних и внуковых пакетов:

#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 я заменил возвращаемое значение в getConfig на $ {$ self. ":: config"}и добавил "нет строгих ссылок".

1 Ответ

1 голос
/ 13 февраля 2012

Ваш код имеет некоторые проблемы:

  • Конструктор 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 для локального отключения этой проверки.

...