我正在尝试继承和扩展具有更具体子类的基类,该子类将从访问器中删除必需的属性,并指定延迟构建的默认类。但是,这样做时,派生类不再将环绕子例程包装在对访问器的调用周围。

我的定义有误吗?

编辑:我应该声明我可以直接继承访问器而无需对其进行修改,并且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/

10-14 10:39