らくで実装する方法


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ますか?

回答:


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

メソッド::修飾子

Perl 5のMooseと同様にクラスメソッドを変更するために使用できるbefore()、after()、around()関数を実装します。内部で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þ ← »

以降の方法はルーチンなので、あなたはメソッド自体のハンドルを取得するにはもう少しコンボリューション方法が必要になりますが、それ以外のだろう、この方法は、まったく同じであるMethodsがのサブクラスである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þ ← »

$wrapped必要であれば、それをアンラップするために、後に、使用することができる手段です。

編集:たとえば、ここから取得したクラスメソッドのハンドルを取得するコードを追加します。


ラップでメソッドがラップされない
ugexe

@ugexe OPはsubsを明示的に参照します。また、それMethodはaRoutine
jjmerelo

混乱していると思います。質問自体は、「クラス内の他のメソッドをラップする」と述べています。Moo周りは、サブルーチンをラップするようなものではありません。
ugexe

@ugexe同じ違い。編集後に言ったように、メソッドはルーチンです。
jjmerelo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.