Значение атрибута становится «методом» внутри Proxy.new (Raku)

Я пытаюсь понять, почему значением атрибута является 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

Кто-нибудь может объяснить, что здесь происходит? Спасибо!

Не говоря уже о том, что код вызывается огромное количество раз... Хотя это кажется ожидаемым поведением в соответствии с этим github.com/rakudo/rakudo/issues/3822

jjmerelo 18.12.2020 18:37

Да, я тоже об этом думал. Спасибо за дополнительную информацию @jjmerelo!

JustThisGuy 18.12.2020 21:22
Некоторые методы, о которых вы не знали, что они существуют в Python.
Некоторые методы, о которых вы не знали, что они существуют в Python.
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
6
2
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что $!string является пустым контейнером к моменту фактического вызова блока. Даже если он объявлен в области действия, к моменту его фактического использования $!str действительно указывает на анонимный метод. Просто добавьте say $!string в свой FETCH или STORE, и вы увидите, что он содержит анонимный Block, печатающий <anon>. Если вы хотите работать с атрибутами, проверьте этот другой ответ SO, чтобы увидеть, как это можно сделать.

Другие вопросы по теме