2017-05-05 15 views
5

To jest ciągłe pytanie z poprzedniego Why is Perl 6's unwrap method a method of Routine?, ale w większości niepowiązanych.Dlaczego nie mogę wywoływać metod meta w Routine :: WrapHandle?

Sposób wrap jest udokumentowana powrotu „wystąpienie prywatnej klasy zwanej WrapHandle Poza tym, że jest dziwny wyciek klasę, która jest prywatna, to nie jest faktycznie nazwa rzeczą, która przychodzi z powrotem Klasa jest faktycznie 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 

Ale oto jest pytanie chciałem zadzwonić .^methods na Routine::WrapHandle to nie działa.

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

to jest taka sama jak próbuje go na nieokreślonej c Nazwa lass:

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

mogę nazwać meta metod na przykład mimo:

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

Co się tam dzieje?

+1

To [leksykalna klasa] (https://github.com/rakudo/rakudo/search?&q=WrapHandle&type=) –

Odpowiedz

6

Definicja Routine::WrapHandle wygląda mniej więcej tak:

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

możemy ignorować otaczającą metody; Ważną kwestią jest to, że mamy do czynienia z leksykalną klasą wewnętrzną zdefiniowaną w zewnętrznej klasie. Upraszczając nieco więcej, otrzymujemy następujący wzór:

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

say try Foo::Bar; #=> Nil 

W pełni kwalifikowana nazwa wewnętrznej klasy będzie zawierać nazwę pakietu otaczającej, ale ze względu na wyraźne my (zamiast niejawnego our), przy czym klasa nie zostanie zainstalowana jako zmienna pakietu, a wyszukiwanie w zakresie plików nie powiedzie się.

Powiązane problemy