Модификация унаследованных методов доступа и сохранение модификаторов - PullRequest
3 голосов
/ 14 июля 2011

Я пытаюсь наследовать и расширять базовый класс более конкретным дочерним классом, который удаляет обязательный атрибут из средства доступа и указывает лениво построенный по умолчанию. Однако при этом производный класс больше не оборачивает подпрограмму вокруг вызовов вокруг метода доступа.

Что я делаю не так в своем определении?

Edit: я должен заявить, что я могу просто наследовать метод доступа без его изменения, и модификаторround все еще работает, и я знаю, что могу сделать что-то вроде установки метода доступа для получения, затем определить метод получения с помощью метода имя средства доступа (то есть 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 голосов
/ 19 июля 2011

За ответ от stvn для того же вопроса о perlmonks , проблема:

На самом деле, это не удаление модификатора «вокруг», вы просто создание нового метода доступа в вашем производном классе, который сам по себе не вокруг-е изд. Позвольте мне объяснить ...

Когда вы создаете атрибут, Moose компилирует методы доступа для Вы и устанавливаете их в пакете, в котором они определены. Эти методы доступа не являются чем-то волшебным (на самом деле, в Moose нет ничего очень волшебный, сложный да, но волшебный нет), и поэтому они передаются по наследству подклассами, как и любой другой метод.

Когда вы «обходите» метод (как вы делаете здесь), Moose будет извлекать саб из пакета, заверните его и замените оригинал завернутая версия. Все это происходит только в локальном пакете, модификаторы методов ничего не знают (или не заботятся) о наследовании.

Когда вы изменяете определение атрибутов с помощью формы + attr, Moose ищет мета-объект атрибута в списке суперклассов, а затем клоны, которые приписывают мета-объект, применяя запрошенные вами изменения и затем устанавливает эти атрибуты в локальный класс. Результат что все методы доступа перекомпилированы в локальный класс, поэтому переопределяет те, которые определены в суперклассе.

Это не наоборот, где средство доступа создается из самого нижнего класса в ISA, а затем по очереди применяются модификаторы обхода вверх по стеку ISA.

...