Почему метод развертки в Perl 6 является рутинным методом?

Там есть unwrap метод, но то, как мне кажется, я должен использовать его не так, как его следует использовать. Кажется, что это должна быть либо отдельная процедура, либо метод в другом классе. Что мне не хватает?

Похоже, что его не волнует, что его вызывающий, пока он получает право Routine::WrapHandle вещь в качестве аргумента. В этом примере я wrap подпрограмма и получить обратно WrapHandle:

sub add-two-numbers ( $n, $m ) { $n + $m }

sub do-some-stuff ( $n, $m, $o ) {
    add-two-numbers(  $n max $m, $m max $o );
    }

put do-some-stuff( 5, 10, 15 );

# now I want to look into do-some-stuff to see what it's
# passing
my $wraphandle = &add-two-numbers.wrap: {
    say "Arguments were (@_[])";
    callwith( |@_ );
    }

put do-some-stuff( 5, 10, 15 );

Затем я могу создать другую и не связанную процедуру unwrapна что:

my &routine = sub { 1 };
&routine.unwrap( $wraphandle );

put do-some-stuff( 5, 10, 15 );

Призыватель к unwrap кажется лишним. Действительно, я могу назвать его как метод класса, и он все еще работает:

Routine.unwrap( $wraphandle );

Но, похоже, это должно быть либо рутиной (так как инвокант не имеет значения):

unwrap( $wraphandle ); # doesn't exist

Или метод на Routine::WrapHandle так как это источник поведения:

$wraphandle.unwrap;  # but, this method doesn't exist in that class

Итак, что мне не хватает в этом методе?

1 ответ

Предположительно, интерфейс был спроектирован одним способом (с подпрограммой, хранящей информацию и способной удалять "пассивные" дескрипторы), но реализовал другой (с дескриптором, уже хранящим всю необходимую информацию, чтобы он мог развернуть себя).

Что касается понятия, что unwrap должен быть метод на дескрипторе: это действительно так, но метод вызывается restore, который Routine.unwrap просто делегирует (ср. core / Routine.pm: 110..113):

method unwrap($handle) {
    $handle.can('restore') && $handle.restore() ||
        X::Routine::Unwrap.new.throw
}

Если вам нужна полная история, кроме core / Routine.pm, есть также Perl6::Metamodel::WrapDispatcher определенный в Perl6 / Metamodel / Dispatchers.nqp. Из того, что я вижу, безусловно, должна быть возможность реализовать оригинальный дизайн, который я предположил, но для этого нужно, чтобы кто-то достаточно сильно чувствовал эту проблему...

Другие вопросы по тегам