为什么我不能在 Routine::WrapHandle 上调用元方法?
Why can't I call meta methods on Routine::WrapHandle?
这是我上一个 Why is Perl 6's unwrap method a method of Routine? 的一个持续问题,但大部分无关。
wrap
方法被记录到 return “一个名为 WrapHandle 的私有 class 的实例。除了泄漏私有的 class 很奇怪之外,它是实际上不是返回的东西的名称。class 实际上是 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
但问题来了。我想在 Routine::WrapHandle
上给 .^methods
打电话。那行不通:
> Routine::WrapHandle.^methods
Could not find symbol '&WrapHandle'
in block <unit> at <unknown file> line 1
这与在未定义的 class 名称上尝试相同:
> 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
那里发生了什么事?
Routine::WrapHandle
的定义看起来像这样:
my class Routine {
method wrap(&wrapper) {
my class WrapHandle { ... }
...
}
}
我们可以忽略周围的方法;重要的一点是我们正在处理在外部 class 中定义的词法内部 class。进一步简化,我们得到以下模式:
package Foo {
my class Bar {}
say Bar.^name; #=> Foo::Bar
}
say try Foo::Bar; #=> Nil
内部 class 的完全限定名称将包括封闭包的名称,但由于显式 my
(而不是隐式 our
),class 将不会作为包变量安装并且在文件范围内查找失败。
这是我上一个 Why is Perl 6's unwrap method a method of Routine? 的一个持续问题,但大部分无关。
wrap
方法被记录到 return “一个名为 WrapHandle 的私有 class 的实例。除了泄漏私有的 class 很奇怪之外,它是实际上不是返回的东西的名称。class 实际上是 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
但问题来了。我想在 Routine::WrapHandle
上给 .^methods
打电话。那行不通:
> Routine::WrapHandle.^methods
Could not find symbol '&WrapHandle'
in block <unit> at <unknown file> line 1
这与在未定义的 class 名称上尝试相同:
> 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
那里发生了什么事?
Routine::WrapHandle
的定义看起来像这样:
my class Routine {
method wrap(&wrapper) {
my class WrapHandle { ... }
...
}
}
我们可以忽略周围的方法;重要的一点是我们正在处理在外部 class 中定义的词法内部 class。进一步简化,我们得到以下模式:
package Foo {
my class Bar {}
say Bar.^name; #=> Foo::Bar
}
say try Foo::Bar; #=> Nil
内部 class 的完全限定名称将包括封闭包的名称,但由于显式 my
(而不是隐式 our
),class 将不会作为包变量安装并且在文件范围内查找失败。