【发布时间】:2011-09-14 19:40:42
【问题描述】:
我想在基类中定义一个所有子类都可以读取和写入的“注册表”哈希,我如何使用 Moose/Perl 来完成?
【问题讨论】:
我想在基类中定义一个所有子类都可以读取和写入的“注册表”哈希,我如何使用 Moose/Perl 来完成?
【问题讨论】:
这是一个简单的 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 };
如果你运行这个程序,你会得到:
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 不喜欢将 refs 作为默认值:default => {} 是被禁止的,您必须将任何引用包装为匿名子例程中的返回值。
【讨论】:
default => {} 以防止此问题成为默认问题。当默认采用裸 ref 时,每个实例都将共享相同的 ref。通过默认评估代码引用,每次都可以创建一个新的引用。在这种情况下,您正在颠覆它并每次都返回相同的 ref。
把它实现为一个方法怎么样:
package BaseClass;
my $hash = {};
sub registry { $hash };
子类只需使用$self->registry->{$key} 访问值并使用$self->registry->{$key} = $value 设置它们。
【讨论】:
【讨论】: