documentation describes override
как:
Способ коррекции является способом явно говоря: «Я перекрывая этот метод из моего суперкласса». Вы можете вызвать super
в этом методе, и он будет работать, как ожидалось. То же самое можно сделать с помощью обычного вызова метода и псевдопакета SUPER::
; это действительно ваш выбор.
То, что вы делаете, противоречит этому определению. С помощью в вашем пакете устанавливается f
. Вы пытаетесь определить еще один f
в том же пакете.
Тот факт, что ваша роль называется Base
, указывает мне, что у вас есть путаница, когда дело доходит до разницы между наследованием и композицией.
purpose of around
это обернуть метод в текущем классе, независимо от того, было ли оно реализовано в одном пакете или в наследство или в составе:
Метод модификаторы могут быть использованы для добавления поведения к способам без изменения определения этих методов.
Простое прямое чтение этих двух фрагментов делает различие понятным для меня.
Когда вы применяете роль, определяющую f
, она сама переопределяет любой унаследованный метод f
. Если вы скажете override 'f'
, вы заявляете о своем намерении снова переопределить f
. Ну, может быть только один метод f
в одном классе. Какой из них следует учитывать? Тот, который вы получаете, применяя роль или тот, который вы только что определили? Для всех целей и целей методы, которые вы получаете от составления роли, точно так же, как методы, которые вы определили вручную в классе. Нет никакой причины a priori
, один должен быть более важным, чем другой.
Думайте об этом как о путешествии авиакомпаний. Подумайте модификаторов метода как классы: Во-первых, бизнес, экономика и т.д. Таким образом, в первом классе, get_dinner_menu
может быть обернут закуски, сладости, десерты и т.д.
С другой стороны, override
, как изменение полета. Это как если бы вы говорили: «Я хочу летать как на TK 1, так и на UIA 213». Без разницы.
Возможно, следующий сценарий будет более понятным, показывая наивную реализацию around
и переопределяя метод без использования override
.
#!/usr/bin/env perl
use strict;
use warnings;
{
package MyRole;
use Moose::Role;
sub f {
print "in role\n";
}
}
{
package X;
use Moose;
with 'MyRole';
around 'f' => sub {
my ($orig, $self) = @_;
print "In wrapper\n";
return $self->$orig(@_);
};
{
my $f = \&f;
{
no warnings 'redefine';
*f = sub {
my ($self) = @_;
print "In wrapper wrapper\n";
return $self->$f(@_);
}
}
}
}
{
package Y;
use Moose;
with 'MyRole';
sub f {
print "In overridden method\n";
}
}
print '=-=' x 22, "\n";
my $x = X->new;
$x->f;
print '=-=' x 22, "\n";
my $y = Y->new;
$y->f;
Выход:
Но почему на Земле, 'around' в этом случае ** ** ли работать? Нельзя ли так сказать «вокруг», чтобы оправдать, что он не должен работать? – porton
Получил. Но разрешение * как * 'sub', так и' around' для одного и того же метода в одном классе выглядит как ошибка дизайна для меня – porton
Нет ничего, что можно было бы получить ***, запрещающее *** 'sub f' и' around 'f ''в том же пакете, потому что создавая роль, которая предоставляет' f' устанавливает 'f' в качестве суб в пакете. Таким образом, этот запрет делает использование 'around' с составленными методами невозможным или трудным. Я не слишком много думал об этом. –