开发者

In Perl/Moose, how do you create a static variable in a parent class that can be accessed from subclasses?

I want to define a "registry" hash in the base class that all subclasses can read a开发者_如何学JAVAnd write to, how do I accomplish this with Moose/Perl?


Here is an implementation with plain Perl OO-style.

You have two classes, BaseClass with global variable $REGISTRY, and DerivedClass which inherits from BaseClass. $REGISTRY is readable and writable from any class instance via registry() method.

#!/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 };

If you run this program you get:

alpha -> 1
beta -> 2

If you prefer an all-Moose solution you should try this one:

#!/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 };

It yields the same result of the OO Perl program. Note how the _REGISTRY attribute is defined. Moose doesn't like refs as default values: default => {} is forbidden, you have to wrap any reference as a return value in an anonymous subroutine.


How about just implement it as a method:

package BaseClass;

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

Sub-classes just use $self->registry->{$key} to access values and $self->registry->{$key} = $value to set them.


MooseX::ClassAttribute

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜