为什么我不能在Routine :: WrapHandle上调用meta方法?

时间:2017-05-05 19:44:17

标签: perl6

这是我之前的一个Why is Perl 6's unwrap method a method of Routine?的问题,但大多数情况下都不相关。

记录wrap方法返回“一个名为WrapHandle的私有类的实例。除了泄漏一个私有类的奇怪之外,它实际上并不是返回的东西的名称。该类是实际上Routine::WrapHandle

$ perl6
> sub f() { say 'f was called' }
sub f () { #`(Sub|140397740886648) ... }
> my $wrap-handle = &f.wrap({ say 'before'; callsame; say 'after' });
Routine::WrapHandle.new

但这是问题所在。我想在.^methods上致电Routine::WrapHandle。这不起作用:

> Routine::WrapHandle.^methods
Could not find symbol '&WrapHandle'
  in block <unit> at <unknown file> line 1

这与在未定义的类名上尝试它相同:

> Foo::Baz.^methods
Could not find symbol '&Baz'
  in block <unit> at <unknown file> line 1

我可以在实例上调用元方法:

> $wrap-handle.^methods
(restore)
> $wrap-handle.^name
Routine::WrapHandle

那里发生了什么?

1 个答案:

答案 0 :(得分:6)

Routine::WrapHandle的定义如下所示:

my class Routine {
    method wrap(&wrapper) {
        my class WrapHandle { ... }
        ...
    }
}

我们可以忽略周围的方法;重要的一点是我们正在处理外部类中定义的词法内部类。简化了一些,我们得出以下模式:

package Foo {
    my class Bar {}
    say Bar.^name; #=> Foo::Bar
}

say try Foo::Bar; #=> Nil

内部类的完全限定名称将包含封闭包的名称,但由于显式my(而不是隐式our),该类将不会安装为包变量和文件范围的查找失败。