Я пытаюсь понять, почему значением атрибута является Str (или что-то еще) вне Proxy.new, но становится методом внутри Proxy.new. Я довел свой код до этого:
#!/usr/bin/env raku
class Foo does Associative {
has Str $.string;
multi method AT-KEY (::?CLASS:D: Str $key) is rw {
say "\nOutside of Proxy: { $!string.raku }";
say "Outside of Proxy: { $!string.^name }";
Proxy.new(
FETCH => method () {
say "FETCH: { $!string.raku }";
say "FETCH: { $!string.^name }";
},
STORE => method ($value) {
say "STORE: { $!string.raku }";
say "STORE: { $!string.^name }";
}
);
}
}
my $string = 'foobar';
my %foo := Foo.new: :$string;
%foo<bar> = 'baz';
say %foo<bar>;
Это результат:
$ ./proxy.raku
Outside of Proxy: "foobar"
Outside of Proxy: Str
STORE: method <anon> (Mu: *%_) { #`(Method|94229743999472) ... }
STORE: Method
Outside of Proxy: "foobar"
Outside of Proxy: Str
FETCH: method <anon> (Mu: *%_) { #`(Method|94229743999616) ... }
FETCH: Method
FETCH: method <anon> (Mu: *%_) { #`(Method|94229743999616) ... }
FETCH: Method
FETCH: method <anon> (Mu: *%_) { #`(Method|94229743999616) ... }
FETCH: Method
FETCH: method <anon> (Mu: *%_) { #`(Method|94229743999616) ... }
FETCH: Method
FETCH: method <anon> (Mu: *%_) { #`(Method|94229743999616) ... }
FETCH: Method
FETCH: method <anon> (Mu: *%_) { #`(Method|94229743999616) ... }
FETCH: Method
FETCH: method <anon> (Mu: *%_) { #`(Method|94229743999616) ... }
FETCH: Method
FETCH: method <anon> (Mu: *%_) { #`(Method|94229743999616) ... }
FETCH: Method
FETCH: method <anon> (Mu: *%_) { #`(Method|94229743999616) ... }
FETCH: Method
True
Кто-нибудь может объяснить, что здесь происходит? Спасибо!
Да, я тоже об этом думал. Спасибо за дополнительную информацию @jjmerelo!
Проблема в том, что $!string является пустым контейнером к моменту фактического вызова блока. Даже если он объявлен в области действия, к моменту его фактического использования $!str действительно указывает на анонимный метод. Просто добавьте say $!string в свой FETCH или STORE, и вы увидите, что он содержит анонимный Block, печатающий <anon>. Если вы хотите работать с атрибутами, проверьте этот другой ответ SO, чтобы увидеть, как это можно сделать.
Не говоря уже о том, что код вызывается огромное количество раз... Хотя это кажется ожидаемым поведением в соответствии с этим github.com/rakudo/rakudo/issues/3822