Cómo implementar alrededor en Raku

13

En Perl, usando Moo, puedes implementar aroundsubs, que envolverán otros métodos en una clase.

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

¿Cómo se puede implementar este comportamiento en Raku , preferiblemente usando a role?

Tyil
fuente

Respuestas:

8

Puede sombrear el método con el rol y luego usar 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
fuente
8

Método :: Modificadores

Implementa las funciones before (), after () y around () que se pueden usar para modificar métodos de clase de manera similar a Moose de Perl 5. Utiliza wrap () internamente y devuelve el controlador de contenedor, por lo que es fácil .restore () el original.

Así es como se implementa el módulo around:

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

Utilizar wrap

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

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

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

Como los métodos son rutinas, necesitará una forma un poco más complicada para manejar el método en sí, pero aparte de eso, el método es exactamente el mismo, ya que Methods son una subclase 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þ ← »

El $wrappedes un asa que se puede usar, más adelante, para desenvolverlo si es necesario.

Editar : para agregar el código para obtener un identificador del método de clase, tomado de aquí , por ejemplo.

jjmerelo
fuente
Envolver no envolver métodos
ugexe
@ugexe el OP se refiere explícitamente a los subs. Además, sólo puede utilizar para que los métodos, ya que es un Methodes unRoutine
jjmerelo
Creo que estas confundido. La pregunta en sí misma dice 'envolver otros métodos en una clase'. Moos alrededor no es como envolver una subrutina.
ugexe
@ugexe misma diferencia. Los métodos son rutinarios, como dije después de la edición.
jjmerelo