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

时间:2011-07-14 18:14:34

标签: 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'"; })。我很惊讶周围的修饰符很容易被抛弃。

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"

1 个答案:

答案 0 :(得分:0)

根据stvn对same question on perlmonks的回复,问题是:

  

实际上,它不是删除'around'修饰符,你很简单   在派生类中创建一个新的访问器,它本身不是   围绕-ED。请允许我解释......

     

当您创建属性时,Moose会编译访问器方法   您将它们安装在定义它们的包中。这些   存取方法并不神奇(实际上,Moose中没有任何东西   非常神奇,复杂的是,但神奇的没有),所以它们是继承的   通过子类,就像任何其他方法一样。

     

当你“围绕”某个方法时(正如你在这里所做的那样),穆斯将提取   包中的sub,包装它并用原来的替换原来的   包装版。这一切都只发生在本地包中   方法修饰符不知道(或关心)有关继承的任何内容。

     

使用+ attr表单更改属性定义时,Moose   在超类列表中查找属性元对象然后   属性元对象的克隆,应用您请求的更改   然后将该属性安装到本地类中。结果是   将所有访问器方法重新编译到本地类中,   因此会覆盖超类中定义的那些。

它没有反过来,其中访问器是从ISA中最底层的类构建的,然后依次应用ISA堆栈中的around修饰符。