perl - Perl 类属性继承
问题描述
我有类属性,例如,某些基类中创建的对象的计数器,
package A;
our $counter = Counter->new; # not just a counter in fact, so initialization code should be inherited by descendants as well
sub new {
$counter++;
bless {}
}
sub get_counter {
$counter
}
package B;
use base 'A';
package main;
B->get_counter();
我希望包 B 有他自己的这个类属性的副本(例如,只计算 B 类的对象),并且从包 A 继承的所有方法都应该处理这个副本。在普通 perl 和 Moo/Moose 中实现这一点的正确方法是什么?似乎 MooX::ClassAttribute 不能被继承。一个丑陋的解决方案是在每个后代中重复属性初始化代码,并在祖先的方法中使用像 ${"${class}::counter"} 这样的符号取消引用来使用实际包名访问这个属性。但似乎应该有更优雅的方式。
解决方案
默认的 Perl 对象模型没有类属性的概念。并且没有像“当一个新的子类被创建时,运行这个代码”这样的钩子。
相反,基类可以使用类名作为键来维护计数器的散列:
package A;
my %counters;
sub new {
my ($class) = @_;
my $counter = $counters{$class} //= Counter->new;
$counter++;
return bless {} => $class;
}
sub get_counter {
my ($self_or_class) = @_;
my $class = (ref $self_or_class) || $self_or_class;
$counters{$class};
}
package B;
use parent -norequire, 'A';
当创建子类的实例时,这将创建一个新的计数器。请注意,方法的第一个参数是类名或对象实例。我们需要使用它new()
作为哈希键。在get_counter()
我写这个的方式中,该方法可以在类和对象上调用以达到相同的效果。
一种类似的技术被称为由内而外的对象,其中将对象字段存储在类持有的哈希中,以便对象本身不包含任何数据。
(为什么parent
而不是base
?该parent
模块仅进行继承,而base
还与fields
您不应该使用的 pragma 集成。)
推荐阅读
- reactjs - 反应原生:useState 没有正确更新
- api - 关于现在配置调用 rest API 到服务的架构疑问
- javascript - 当页面滚动到某个点时,CSS/JS 将类添加到 div
- javascript - 通过导航栏隐藏到同一页面
- c++ - How can I fix an assertion failure that states 'vector subscript out of range'
- postgresql - 架构公共的 Supabase 客户端权限被拒绝
- visual-studio - 无法安装神经核:在 spaCy 中使用神经网络的共指解析
- android - 特定文件部分的 Android Visualizer
- javascript - 我希望我的中间件等到特定操作完全完成
- javascript - 我试图在 javasript/html 中的密码中仅放置 3 个特殊字符(@ # $)