Раку сбивает с толку постфикс, = поведение оператора - PullRequest
7 голосов
/ 03 февраля 2020

Эта страница документации raku говорит, что оператор ,= должен объединить

содержимое переменной с левой стороны и выражение с правой стороны

в зависимости от класса. В документации также приведен пример с переменной Hash:

my %a = :11a, :22b;
%a ,= :33x;
say %a # OUTPUT: «{a => 11, b => 22, x => 33}␤»

Это работает для меня, но когда я пытаюсь сделать то же самое для Array, происходит что-то непонятное:

my @a = 1, 2;
@a ,= 3;
say @a 

А на выходе получается что-то вроде (\Array_94393785458840 = [Array_94393785458840 3]). Однако я ожидаю, что результат будет [1, 2, 3].

Мой вопрос: Это ожидаемое поведение? И если да, то какова цель такой операции?

Ответы [ 2 ]

10 голосов
/ 03 февраля 2020
foo ,= bar

- это сокращение от

foo = foo, bar

Таким образом,

@a ,= 3

- это сокращение от:

@a = @a, 3;

Во время рефакторинга Большого списка в 2015 году, правило единственного аргумента стало активным везде. Так как правая часть выражения не один аргумент, @a в правой части не будет сплющен.

Так эффективно, вы создаете самоссылочный массив, в котором первый элемент ссылается на себя (это то, что say пытается вам сказать).

По причинам, о которых я больше не понимаю, То же самое не применяется к объектам, выполняющим ассоциативную роль. Таким образом, в этом случае %a действительно сглаживается, добавляя тем самым данное Pair к Ха sh.

my %a = :11a, :22b;
%a = %a, :33x;
say %a # OUTPUT: «{a => 11, b => 22, x => 33}␤»

Чтобы вернуться к вашему вопросу: в в случае с массивом, я не думаю, что есть много смысла для операции ,=. До Великого Рефактора Списка, он мог сделать то, что вы ожидали. Но это было бы несовместимо с другими ситуациями, и согласованность считалась более важной (потому что до Великого Списка Факторов, когда что-то сглаживалось, а когда нет, было довольно произвольно и много раз источником WAT вместо DWIM).

1 голос
/ 06 февраля 2020

для тех, кто менее знаком с raku, легко выровнять любой массив с помощью '|' вот так ... @a = |@a, :33; (за счет дополнительного оператора)

...