Comment mettre en œuvre autour de Raku

13

En Perl, en utilisant Moo, vous pouvez implémenter des aroundsous-marins, qui encapsuleront d'autres méthodes dans une 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";
};

Comment ce comportement peut-il être implémenté dans Raku , de préférence en utilisant un role?

Tyil
la source

Réponses:

8

Vous pouvez masquer la méthode avec le rôle, puis utiliser 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
la source
8

Méthode :: Modificateurs

Implémente les fonctions before (), after () et around () qui peuvent être utilisées pour modifier les méthodes de classe de manière similaire à Moose de Perl 5. Il utilise wrap () en interne et renvoie le gestionnaire de wrapper, il est donc facile de .restore () l'original.

Voici comment le module implémente around:

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

Utilisation wrap

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

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

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

Étant donné que les méthodes sont des routines, vous aurez besoin d'un moyen un peu plus compliqué pour obtenir une poignée sur la méthode elle-même, mais à part cela, la méthode est exactement la même, car Methods est une sous-classe de 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þ ← »

Le $wrappedest une poignée qui peut être utilisée plus tard pour la déballer si nécessaire.

Edit : pour ajouter le code pour obtenir une poignée sur la méthode de classe, prise ici , par exemple.

jjmerelo
la source
Wrap ne pas envelopper les méthodes
ugexe
@ugexe l'OP fait explicitement référence aux sous-marins. En outre, vous pouvez simplement l'utiliser pour les méthodes, car c'est MethodunRoutine
jjmerelo
Je pense que vous êtes confus. La question elle-même dit «envelopper d'autres méthodes dans une classe». Moos autour n'a rien à voir avec un sous-programme.
ugexe
@ugexe même différence. Les méthodes sont des routines, comme je l'ai dit après la modification.
jjmerelo