Como implementar em Raku


13

No Perl, usando Moo, você pode implementar aroundsubs, que envolvem outros métodos em uma 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";
};

Como esse comportamento pode ser implementado no Raku , de preferência usando um role?

Respostas:


8

Você pode sombrear o método com a função e, em seguida, 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

8

Método :: Modificadores

Implementa as funções before (), after () e around () que podem ser usadas para modificar métodos de classe de maneira semelhante ao Moose do Perl 5. Ele usa wrap () internamente e retorna o manipulador do wrapper, portanto é fácil .restore () o original.

É assim que o módulo implementa around:

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

6

Usar wrap

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

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

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

Como os métodos são rotinas, você precisará de uma maneira um pouco mais complicada de lidar com o próprio método, mas, além disso, o método é exatamente o mesmo, uma vez que Methods são uma subclasse 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þ ← »

O $wrappedé um identificador que pode ser usado, posteriormente, para desembrulhá-lo, se necessário.

Editar : para adicionar o código para obter um identificador do método de classe, extraído daqui , por exemplo.


O wrap não envolve métodos
ugexe 6/11/19

@ugexe o OP se refere explicitamente a subs. Além disso, você pode simplesmente usar isso para métodos, já que é um Methodé umRoutine
jjmerelo

Eu acho que você está confuso. A própria pergunta afirma 'envolver outros métodos em uma classe'. Moos ao redor não é nada como quebrar uma sub-rotina.
ugexe

@ugexe mesma diferença. Métodos são rotinas, como eu disse após a edição.
jjmerelo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.