我想在基类中定义一个所有子类都可以读写的"注册表"哈希,如何使用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 };
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 => {}禁止,你必须将任何引用包装为匿名子例程中的返回值.
如何实现它作为一种方法:
package BaseClass;
my $hash = {};
sub registry { $hash };
Run Code Online (Sandbox Code Playgroud)
子类只用于$self->registry->{$key}访问值和$self->registry->{$key} = $value设置它们.