在Perl/Moose中,如何在可以从子类访问的父类中创建静态变量?

qod*_*nja 2 perl static moose

我想在基类中定义一个所有子类都可以读写的"注册表"哈希,如何使用Moose/Perl实现这一点?

Mar*_*lis 6

这是一个简单的Perl OO风格的实现.

你有两个班,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 };
Run Code Online (Sandbox Code Playgroud)

如果你运行这个程序,你会得到:

alpha -> 1
beta -> 2
Run Code Online (Sandbox Code Playgroud)

如果你更喜欢全驼鹿解决方案,你应该试试这个:

#!/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 };
Run Code Online (Sandbox Code Playgroud)

它产生与OO Perl程序相同的结果.请注意_REGISTRY属性是如何定义的.Moose不喜欢refs作为默认值:default => {}禁止,你必须将任何引用包装为匿名子例程中的返回值.

  • Moose实际上阻止了`default => {}`来防止这个问题成为默认问题.当默认采用裸引用时,每个实例都将共享相同的引用.使用默认评估代码引用时,每次都可以创建新的引用.在这种情况下,你是颠覆它并且每次都返回相同的ref. (2认同)

Eri*_*ikR 5

如何实现它作为一种方法:

package BaseClass;

my $hash = {};
sub registry { $hash };
Run Code Online (Sandbox Code Playgroud)

子类只用于$self->registry->{$key}访问值和$self->registry->{$key} = $value设置它们.