Come implementare in giro a Raku


13

In Perl, usando Moo, puoi implementare aroundsottotitoli, che avvolgeranno altri metodi in una classe.

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

Come può essere implementato questo comportamento in Raku , preferibilmente usando un role?

Risposte:


8

È possibile ombreggiare il metodo con il ruolo e quindi utilizzare callwith:

class Foo {
    method meth { say 2 }
}

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

$foo.meth

8

Metodo :: modificatori

Implementa le funzioni before (), after () e around () che possono essere utilizzate per modificare i metodi di classe in modo simile a Moose di Perl 5. Utilizza internamente wrap () e restituisce il gestore wrapper, quindi è facile .restore () l'originale.

Ecco come implementa il modulo around:

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

6

Uso wrap

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

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

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

Poiché i metodi sono routine, avrai bisogno di un modo leggermente più contorto per ottenere un handle sul metodo stesso, ma a parte questo, il metodo è esattamente lo stesso, poiché Methods è una sottoclasse di 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þ ← »

Il $wrappedè una maniglia che può essere utilizzato, in seguito, a scartare, se necessario.

Modifica : per aggiungere il codice per ottenere un handle sul metodo class, preso da qui , per esempio.


Il wrapping non include i metodi
ugexe il

@ugexe l'OP si riferisce esplicitamente ai sottotitoli. Inoltre, puoi semplicemente usarlo per i metodi, poiché è a Methodis aRoutine
jjmerelo il

Penso che tu sia confuso. La domanda stessa afferma "avvolgere altri metodi in una classe". Moos around non è come avvolgere una subroutine.
ugexe,

@ugexe stessa differenza. I metodi sono routine, come ho detto dopo la modifica.
jjmerelo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.