Як реалізувати навколо в Раку


13

У Perl, використовуючи Moo, ви можете реалізувати aroundsubs, які будуть обговорювати інші методи класу.

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

Як така поведінка може бути реалізована в Раку , бажано, використовуючи 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

Метод :: Модифікатори

Реалізує функції до (), після () та навколо (), які можна використовувати для зміни методів класів аналогічно Moose Perl 5. Він використовує wrap () внутрішньо і повертає обробник обгортки, тому його легко відновити ().

Ось як реалізується модуль 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ручка, яку згодом можна використовувати, щоб розмотати її за потреби.

Редагувати : щоб додати код, щоб отримати ручку методу класу, взятого звідси , наприклад.


Wrap не
обертає

@ugexe ОП прямо посилається на підс. Крім того, ви можете просто використовувати це для методів, оскільки це MethodaRoutine
jjmerelo

Я думаю, ти розгублений. У самому питанні йдеться про "обгортання інших методів у класі". Moos навколо - це не що інше, як обгортання підпрограми.
ugexe

@ugexe та ж різниця. Методи - звичайні, як я вже сказав після редагування.
jjmerelo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.