2017-05-05 8 views
5

これは私の前の1つであるWhy is Perl 6's unwrap method a method of Routine?からの継続的な質問ですが、ほとんど無関係です。Routine :: WrapHandleでメタメソッドを呼び出せないのはなぜですか?

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 

しかし、ここでは質問です私はRoutine::WrapHandle.^methodsを呼び出すしたい動作しないこと:。。

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

これは未定義Cでそれをしようとすると同じです小娘名:

> 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

[字句クラス](https://github.com/rakudo/rakudo/search?&q=WrapHandle&type=) –

答えて

6

Routine::WrapHandleの定義は、次のようなものになります。私たちは、周囲のメソッドを無視することができます

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

を。重要なことは、外部クラス内で定義されている字句的な内部クラスを扱っていることです。 、(代わりに暗黙のourの)内部クラスの完全修飾名を囲むパッケージの名前が含まれます

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

say try Foo::Bar; #=> Nil 

が、原因を明示的にmy:いくつかのより多くの簡素化、我々は次のパターンに到着しますクラスはパッケージ変数としてインストールされず、ファイルスコープでの検索が失敗します。

関連する問題