Как реализовать в Раку - PullRequest
       19

Как реализовать в Раку

8 голосов
/ 06 ноября 2019

В 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 , предпочтительно с использованием role?

Ответы [ 3 ]

6 голосов
/ 06 ноября 2019

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

Реализует функции before (), after () и around (), которые могут использоваться для аналогичного изменения методов классаPerl 5's Moose. Он использует wrap () внутри и возвращает обработчик обертки, поэтому легко .restore () оригинал.

Вот как модуль реализует around:

sub around ($class, $method-name, &closure) is export
{
  $class.^find_method($method-name).wrap(method { closure(); });
}
6 голосов
/ 06 ноября 2019

Вы можете скрыть метод с ролью и затем использовать callwith:

class Foo {
    method meth { say 2 }
}

my $foo = Foo.new but role :: {
    method meth(|c) { say 1; callwith(|c); say 3 }
};

$foo.meth
3 голосов
/ 06 ноября 2019

Использование wrap

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

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

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

Поскольку методы являются подпрограммами, вам понадобится немного более сложный способ получить представление о самом методе, но кроме этого,метод точно такой же, поскольку Method s являются подклассом Routine s

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 - это дескриптор, который можетпозже будет использоваться, чтобы развернуть его, если необходимо.

Редактировать : добавить код, чтобы получить дескриптор метода класса, взятый из здесь , дляэкземпляр.

...