perl - 修改继承的访问器并保留修饰符

标签 perl inheritance object moose

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

我的定义哪里做错了?

编辑:我应该声明我可以简单地继承访问器而不修改它并且 around 修饰符仍然有效,而且我知道我可以做一些事情,比如将访问器设置为有一个 getter,然后定义一个 getter 方法访问器的名称(即 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 的回复,问题是:

Actually, it is not removing the 'around' modifier, you are simply creating a new accessor in your derived class, which itself is not around-ed. Allow me to explain ...

When you create an attribute, Moose compiles the accessor methods for you and installs them in the package in which they are defined. These accessor methods are nothing magical (in fact, nothing in Moose is very magical, complex yes, but magical no), and so they are inherited by subclasses just as any other method would be.

When you "around" a method (as you are doing here) Moose will extract the sub from the package, wrap it and replace the original with the wrapped version. This all happens in the local package only, the method modifiers do not know (or care) anything about inheritance.

When you change an attributes definition using the +attr form, Moose looks up the attribute meta-object in the superclass list and then clones that attribute meta-object, applying the changes you requested and then installs that attributes into the local class. The result is that all accessor methods are re-compiled into the local class, therefore overriding the ones defined in the superclass.

它不会反过来,访问器是从 ISA 中最底层的类构建的,然后依次应用 ISA 堆栈上的周围修饰符。

关于perl - 修改继承的访问器并保留修饰符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6697987/

相关文章:

postgresql - 当我尝试使用 DBI 执行查询时,为什么会出现错误 "called with 1 bind variables when 0 are needed"?

mysql - 抛出“不是数组引用”错误

java - Hibernate 多对多连接表不为继承的实体保留

C++:空类对象的大小是多少?

javascript - 如何制作可以在多个级别引用的类/对象

python - 尝试读取 DBM 文件

javascript - JS 继承 : calling the parent's function from within the child's function

c++ - 来自不同类别的对象的 vector

json - Angular2 从 JSON 解析为对象

regex - Perl 一行代码将第一个字符转换为大写 - 逻辑理解