Анонимные контейнеры

Определите переменную $a:

my $a = 123;

Определите переменную без знака, связанную с $a:

my \b = $a;

Мы можем изменить значение $a через b:

b = 234;

say $a;

Это должно отобразить 234.

Насколько я понимаю, это работает, потому что b установлен в контейнер, связанный с $a.

Есть ли способ определить анонимный контейнер? Т.е. что-то вроде этого:

my \b = container(123);

Поскольку b связан с контейнером, назначение будет работать как в первом примере:

b = 234;

person dharmatech    schedule 23.05.2016    source источник


Ответы (2)


Вы ищете my $ вместо my $a.

(Спасибо @ BradGilbert ++ за исправление очень простой ошибки в первой версии этого ответа, в которой я предложил использовать только $ вместо my $; см. Комментарии к этому ответу.)


Обратите внимание, что =, когда он используется в качестве оператора для инициализации объявления с косой чертой сигил, связывает (действует так же, как :=), не задание.

Следующий код объявляет анонимный контейнер Scalar, назначает (копирует) 123 ему 1, объявляет символ с косой чертой a и связывает a к Scalar 1:

my \a = my $ = 123;
#            ???? *Assigns* 123 to an anonymous Scalar
#     ???? *Binds* a to the anonymous Scalar 
say a;                     # 123
a = 234;
say a;                     # 234

Сноска

1 В выражении foo = bar (присвоение) принято говорить, что один назначает (копирует) значение правой стороны (или значение переменной) в (в) левую переменную / контейнер. В выражении baz := waldo (привязка) принято говорить, что один связывает символ / переменную левой стороны с правой < / em> ручная переменная / контейнер / значение.

person raiph    schedule 23.05.2016
comment
@dharmatech Обратите внимание, что просто $ сам по себе то же самое, что и state $, вместо этого вы можете захотеть my $, особенно если это в подпрограмме. my \a = my $ = 123; - person Brad Gilbert; 23.05.2016
comment
@BradGilbert: Есть ли смысловое влияние? Если my \a = $ = 123 находится в подпрограмме, компилятор создает как переменную a, так и анонимный контейнер при первом обнаружении этой строки. В конце подпрограммы переменная a передается сборщику мусора, а анонимный контейнер - нет. Если та же строка встречается снова (например, повторный вызов подпрограммы), переменная a восстанавливается, а анон $ - нет. Назначения все еще выполняются, поэтому a по-прежнему получает 123. my \a = my $ = 123 означает, что аноним $ удаляется одновременно с переменной a, которая влияет на использование памяти и скорость. - person raiph; 23.05.2016
comment
@raiph нет, если бы вы могли участвовать в подпрограмме более чем в одном потоке за раз. sub c (\v){my \a = $ = v; await Promise.in: (1..5).pick; say "{v} {'!' x (v !eqv a)}eqv {a}"; }; eager (1..5).race(:batch(1)).map: &c - person Brad Gilbert; 23.05.2016

Кажется, это способ назначить b контейнер, у которого нет другого имени в той же области, что и b:

my \b = { my $a = 123; $a; }();

b = 234;

say b;

Итак, исходя из этого подхода, container можно определить следующим образом:

sub container(\val) is rw { my $var = val; $var; }

Пример:

my \b = container(123);

b = 234;

say b;

Отображает 234.

person dharmatech    schedule 23.05.2016
comment
или намного проще sub container(\val) is rw { my $ = val } - person Brad Gilbert; 23.05.2016
comment
или даже sub container($c is copy) is rw { $c } - person Christoph; 23.05.2016