Die documentation describes override
als:
Eine Überschreibung Methode eine Möglichkeit ausdrücklich sagt, ist „Ich habe diese Methode von meiner übergeordneten Klasse bin überwiegende“. Sie können innerhalb dieser Methode super
aufrufen, und es wird wie erwartet funktionieren. Dasselbe kann mit einem normalen Methodenaufruf und dem Pseudo-Paket SUPER::
erreicht werden; es ist wirklich deine Entscheidung.
Was Sie tun, widerspricht dieser Definition. Mit einer Rolle ist f
in Ihrem Paket installiert. Sie versuchen, ein anderes f
in demselben Paket zu definieren.
Die Tatsache, dass Ihre Rolle Base
genannt wird bedeutet für mich, dass Sie etwas Verwirrung haben, wenn es um den Unterschied zwischen Vererbung und Zusammensetzung kommt.
Die purpose of around
ist, ein Verfahren in der aktuellen Klasse zu wickeln, unabhängig davon, ob es in dem gleichen Paket implementiert wurde oder ererbten oder zusammengesetzt:
Method Modifikatoren verwendet werden kann, ohne Änderung der Definition Verhalten Methoden hinzufügen dieser Methoden.
Nur ein einfaches Lesen dieser zwei Schnipsel macht die Unterscheidung für mich klar.
Wenn Sie die Rolle anwenden, die f
definiert, überschreibt diese selbst alle geerbten Methoden f
. Wenn Sie dann override 'f'
sagen, erklären Sie Ihre Absicht, f
erneut zu überschreiben. Nun, es kann nur eine Methode f
in einer Klasse geben. Welcher sollte zählen? Der eine, den Sie bekommen, indem Sie die Rolle anwenden, oder die, die Sie gerade definiert haben? Die Methoden, die Sie beim Erstellen einer Rolle erhalten, sind in etwa dieselben wie Methoden, die Sie manuell in der Klasse definiert haben. Es gibt keinen Grund a priori
einer sollte wichtiger sein als der andere.
Betrachten Sie dies als Flugreisen. Denken Sie an die Methode Modifikatoren als Klassen: Erstens, Wirtschaft, Wirtschaft usw. Also, in der ersten Klasse, get_dinner_menu
vielleicht verpackt mit Vorspeisen, Süßigkeiten, Desserts usw.
Auf der anderen Seite, override
ist wie die Flucht zu verändern. Es ist, als ob du sagst "Ich möchte sowohl auf TK 1 als auch auf UIA 213 fliegen". Macht keinen Sinn.
Vielleicht wird das folgende Skript die Dinge etwas klarer machen, indem es eine naive Implementierung von around
zeigt und eine Methode überschreibt, ohne override
zu verwenden.
#!/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;
Ausgang:
Aber warum auf der Erde, 'around' in diesem Fall ** nicht ** arbeiten? Kann man nicht über "herum" sagen, dass es nicht funktionieren soll? – porton
Verstanden. Aber "sowohl" als auch "um" für die gleiche Methode in einer Klasse zuzulassen, sieht für mich wie ein Designfehler aus. – porton
Es gibt nichts, was man durch *** verbieten von *** 'sub f' und' around'f erreichen könnte '' im selben Paket, weil das Komponieren einer Rolle, die 'f' bereitstellt, 'f' als eine Untereinheit in dem Paket installiert. Dieses Verbot macht es also unmöglich, "um" mit zusammengesetzten Methoden zu umgehen oder sie zu umgehen. Ich habe nicht zu viel darüber nachgedacht. –