我正在尝试继承和扩展具有更具体子类的基类,该子类将从访问器中删除必需的属性,并指定延迟构建的默认类。但是,这样做时,派生类不再将环绕子例程包装在对访问器的调用周围。
我的定义有误吗?
编辑:我应该声明我可以直接继承访问器而无需对其进行修改,并且around修饰符仍然有效,并且我知道我可以执行一些操作,例如将访问器设置为具有吸气剂,然后使用名称来定义吸气剂方法。访问器(即sub attr { my $self = shift; my $value = $self->_get_attr; return "The value of attr is '$value'"; }
)。我只是惊讶地发现around修饰符这么容易被丢弃。
use strict;
use warnings;
use 5.010;
package My::Base;
use Moose;
has 'attr' => (is => 'ro', isa => 'Str', required => 1);
around 'attr' => sub {
my $orig = shift;
my $self = shift;
my $response = $self->$orig(@_);
return "The value of attr is '$response'"
};
package My::Derived;
use Moose;
extends 'My::Base';
has '+attr' => (required => 0, lazy_build => 1);
sub _build_attr {
return "default value";
}
package main;
my $base = My::Base->new(attr => 'constructor value');
say $base->attr; # "The value of attr is 'constructor value'"
my $derived = My::Derived->new();
say $derived->attr; # "default value"
最佳答案
根据stvn对same question on perlmonks的答复,问题是:
实际上,它并没有删除“ around”修饰符,您只是
在派生类中创建一个新的访问器,它本身不是
围绕ed。请允许我解释一下...
创建属性时,Moose编译以下对象的访问器方法:
您并将其安装在定义它们的包中。这些
访问器方法没有什么神奇的(事实上,Moose中没有什么是
非常神奇,复杂是,但是神奇否),因此它们是继承的
子类,就像其他方法一样。
当您“围绕”某个方法(如此处操作)时,Moose将提取
包装中的子包装,将其包装并用
包装版本。所有这些仅在本地包中发生
方法修饰符对继承一无所知。
当您使用+ attr表单更改属性定义时,Moose
在超类列表中查找属性元对象,然后
克隆属性元对象,应用您请求的更改
然后将该属性安装到本地类中。结果是
将所有访问器方法重新编译到本地类中,
因此将覆盖超类中定义的那些。
它不会反过来,即访问器是从ISA中最底层的类构建的,然后依次应用ISA堆栈中的around修饰符。
关于perl - 修改继承的访问器并保留修饰符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6697987/