Wie man in Raku umsetzt

13

In Perl können MooSie mit aroundsubs Subs implementieren , die andere Methoden in einer Klasse umschließen.

around INSERT => sub {
    my $orig = shift;
    my $self = shift;

    print "Before the original sub\n";
    my $rv  = $orig->($self, @_);
    print "After the original sub\n";
};

Wie kann dieses Verhalten in Raku implementiert werden , vorzugsweise mit a role?

Tyil
quelle

Antworten:

8

Sie können die Methode mit der Rolle beschatten und dann Folgendes verwenden callwith:

class Foo {
    method meth { say 2 }
}

my $foo = Foo.new but role :: {
    method meth(|c) { say 1; callwith(|c); say 3 }
};

$foo.meth
ugexe
quelle
8

Methode :: Modifikatoren

Implementiert Funktionen vor (), nach () und um (), mit denen Klassenmethoden ähnlich wie in Moose von Perl 5 geändert werden können. Es verwendet intern wrap () und gibt den Wrapper-Handler zurück, sodass es einfach ist, das Original wiederherzustellen.

So implementiert das Modul around:

sub around ($class, $method-name, &closure) is export
{
  $class.^find_method($method-name).wrap(method { closure(); });
}
Holli
quelle
6

Verwenden wrap

sub bar () { return "baþ" };

my $wrapped = &bar.wrap( { " → " ~ callsame() ~ " ← " } );

say bar(); # OUTPUT:  «→ baþ ← »

Da Methoden Routinen sind, benötigen Sie eine etwas kompliziertere Methode, um die Methode selbst in den Griff zu bekommen. Ansonsten ist die Methode genau dieselbe, da Methods eine Unterklasse von Routines ist

class Baz {
    method bar () { return "baþ" };
}

my &method_bar = Baz.^find_method("bar");
my $wrapped = &method_bar.wrap( { " → " ~ callsame() ~ " ← " } );

say Baz.bar(); # OUTPUT:  «→ baþ ← »

Das $wrappedist ein Griff, der verwendet werden kann, später, es auszupacken , wenn nötig.

Bearbeiten : Zum Hinzufügen des Codes, um ein Handle für die Klassenmethode zu erhalten, beispielsweise von hier aus.

jjmerelo
quelle
Wrap
verpackt
@ugexe das OP bezieht sich explizit auf Subs. Sie können das auch nur für Methoden verwenden, da es ein MethodistRoutine
jjmerelo
Ich denke du bist verwirrt. Die Frage selbst lautet "Umschließen anderer Methoden in einer Klasse". Moos around ist nichts anderes als das Umschließen einer Unterroutine.
ugexe
@ugexe gleichen Unterschied. Methoden sind Routinen, wie ich nach der Bearbeitung sagte.
Jjmerelo