Jak zaimplementować w Raku

13

W Perlu, używając Moo, możesz zaimplementować aroundnapisy, które owijają inne metody w klasie.

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";
};

Jak to zachowanie można zaimplementować w Raku , najlepiej używając role?

Tyil
źródło

Odpowiedzi:

8

Możesz śledzić metodę za pomocą roli, a następnie użyć 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
źródło
8

Metoda :: Modyfikatory

Implementuje funkcje before (), after () i around (), których można używać do modyfikowania metod klasowych podobnie jak Perl 5's Moose. Wykorzystuje wewnętrznie wrap () i zwraca moduł obsługi opakowania, dzięki czemu łatwo jest .restore () oryginał.

W ten sposób moduł implementuje around:

sub around ($class, $method-name, &closure) is export
{
  $class.^find_method($method-name).wrap(method { closure(); });
}
Holli
źródło
6

Posługiwać się wrap

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

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

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

Ponieważ metody są procedurami, potrzebujesz nieco bardziej skomplikowanego sposobu, aby uzyskać uchwyt na samej metodzie, ale poza tym metoda jest dokładnie taka sama, ponieważ Methods są podklasą Routines

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

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

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

$wrappedJest uchwyt, który może być używany, później, do otwierania go w razie potrzeby.

Edycja : aby dodać kod, aby uzyskać uchwyt metody klasy , na przykład pobranej stąd .

jjmerelo
źródło
Zawijanie
@ugexe OP odnosi się wprost do sub. Możesz także użyć tego do metod, ponieważ Methodjest toRoutine
jjmerelo,
Myślę, że jesteś zdezorientowany. Samo pytanie brzmi: „owiń inne metody w klasie”. MooW okolicy nie ma jak zawijanie podprogramu.
ugexe
@ugexe taka sama różnica. Metody są procedurami, jak powiedziałem po edycji.
jjmerelo,