В Perl / Moose, как создать статическую переменную в родительском классе, к которой можно получить доступ из подклассов? - PullRequest
2 голосов
/ 14 сентября 2011

Я хочу определить хэш «реестра» в базовом классе, который могут читать и записывать все подклассы, как мне это сделать с помощью Moose / Perl?

Ответы [ 3 ]

6 голосов
/ 15 сентября 2011

Вот реализация с простым OO-стилем Perl.

У вас есть два класса, BaseClass с глобальной переменной $REGISTRY и DerivedClass, который наследуется от BaseClass. $REGISTRY доступен для чтения и записи из любого экземпляра класса с помощью метода registry().

#!/usr/bin/env perl

use 5.012;
use strict;

package BaseClass;

our $REGISTRY = {};

sub new {
    my $class = shift;
    my $self  = {};
    bless $self, $class;
    return $self;
}

sub registry {
    my $self = shift;
    return $REGISTRY;
}

package DerivedClass;

push our @ISA, 'BaseClass';

package main;

my $base    = BaseClass->new;
$base->registry->{ alpha } = 1;

my $derived = DerivedClass->new;
$derived->registry->{ beta } = 2;

say $_, ' -> ', $base->registry->{ $_ } foreach keys %{ $base->registry };

Если вы запустите эту программу, вы получите:

alpha -> 1
beta -> 2

Если вы предпочитаете решение для всех Moose, попробуйте следующее:

#!/usr/bin/env perl

use 5.012;
use strict;

package BaseClass;
use Moose;

our $_REGISTRY = {};
has '_REGISTRY' => (
    is      => 'rw',
    isa     => 'HashRef',
    default => sub { return $_REGISTRY }
);

sub registry {
    my $self = shift;
    return $self->_REGISTRY;
}

__PACKAGE__->meta->make_immutable;
no Moose;

package DerivedClass;
use Moose;

use base 'BaseClass';

__PACKAGE__->meta->make_immutable;
no Moose;

package main;

my $base    = BaseClass->new;
$base->registry->{ alpha } = 1;

my $derived = DerivedClass->new;
$derived->registry->{ beta } = 2;

say $_, ' -> ', $base->registry->{ $_ } foreach keys %{ $base->registry };

Он дает тот же результат, что и программа OO Perl. Обратите внимание, как определяется атрибут _REGISTRY. Moose не любит ссылки в качестве значений по умолчанию: default => {} запрещено, вы должны заключить любую ссылку в качестве возвращаемого значения в анонимную подпрограмму.

5 голосов
/ 15 сентября 2011

Как насчет просто реализовать его как метод:

package BaseClass;

my $hash = {};
sub registry { $hash };

Подклассы просто используют $self->registry->{$key} для доступа к значениям и $self->registry->{$key} = $value для их установки.

4 голосов
/ 15 сентября 2011
...