如何在Raku中实施


13

在Perl中,可以使用Moo实现子around,这些子将包装类中的其他方法。

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

如何在Raku中实现此行为,最好使用a role

Answers:


8

您可以使用角色将方法隐藏起来,然后使用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

方法::修饰符

实现before(),after()和around()函数,这些函数可用于类似于Perl 5的Moose修改类方法。它在内部使用wrap(),并返回包装器处理程序,因此很容易对原始文件进行.restore()。

这是模块的实现方式around

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

6

采用 wrap

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

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

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

由于方法是例程,因此您需要一种稍微复杂的方法来获取方法本身的句柄,但除此之外,该方法完全相同,因为Methodss的子类Routine

class Baz {
    method bar () { return "baþ" };
}

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

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

$wrapped是可以使用的,以后,如果需要的话解开它的手柄。

编辑:添加代码以获取类方法的句柄,例如,从此处获取。


包装不包装方法
-ugexe

@ugexe OP明确地指代潜艇。此外,您可以将其用于方法,因为它Method是一个Routine
jjmerelo

我觉得你很困惑。问题本身指出“包装类中的其他方法”。Moos就像包装一个子程序一样。
ugexe

@ugexe相同。正如我在编辑后所说的,方法就是例程。
jjmerelo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.