Why is Perl 6's unwrap method a method of Routine?

☆樱花仙子☆ 提交于 2019-12-10 13:13:08

问题


There's an unwrap method, but the way it seems I'm supposed to use it isn't the way it should be used. It seems like it should either be a standalone routine or a method in a different class. What am I missing?

It appears that it doesn't care what its invocant is as long as it gets the right Routine::WrapHandle thingy as an argument. In this example, I wrap a subroutine and get back a 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 );

Then, I can create a different and unrelated routine and call unwrap on that:

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

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

The invocant to unwrap seems superfluous. Indeed, I can call it as a class method and it still works:

Routine.unwrap( $wraphandle );

But, it seems this should either be a routine (since the invocant doesn't matter):

unwrap( $wraphandle ); # doesn't exist

Or a method on Routine::WrapHandle since that's the source of the behavior:

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

So, what am I missing about this method?


回答1:


At a guess, the interface was designed one way (with the routine keeping the information and being able to remove 'passive' handles), but implemented another (with the handle already keeping all required information so it can unwrap itself).

As to the notion that unwrap should perhaps be a method on the handle: It actually is, but the method is called restore, which Routine.unwrap merely delegates to (cf core/Routine.pm:110..113):

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

If you want the full story, besides core/Routine.pm, there's also Perl6::Metamodel::WrapDispatcher defined in Perl6/Metamodel/Dispatchers.nqp. From what I can see, it certainly should be possible to implement the original design I conjectured, but it would need someone feeling strongly enough about the issue to actually do it...



来源:https://stackoverflow.com/questions/43793769/why-is-perl-6s-unwrap-method-a-method-of-routine

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!