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?

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

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(); });
}

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.


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.