Raku confusing postfix ,= operator behavior
Asked Answered
N

3

8

This raku documentation page says operator ,= is supposed to concatenate

the contents of the variable on the left hand side and the expression on the right hand side

in a class-dependent way. The documentation also provides an example with a Hash variable:

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

This works for me, but when I try to do the same for an Array something confusing happens:

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

And the output is something like (\Array_94393785458840 = [Array_94393785458840 3]). I would expect however the result be [1, 2, 3].

My question is: Is this the expected behavior? And if so, what is the purpose of such an operation?

Naker answered 3/2, 2020 at 15:27 Comment(0)
S
10
foo ,= bar

is short for

foo = foo, bar

So,

@a ,= 3

is short for:

@a = @a, 3;

During the Great List Refactor in 2015, the single argument rule became active everywhere. Since the right hand side of the expression is not a single argument, the @aon the right hand side, will not get flattened.

So effectively, you're creating a self-referential Array, in which the first element refers to itself (which is what the say is trying to tell you).

For reasons I'm not too clear about anymore, the same does not apply to objects doing the Associative role. So in that case, the %a does get flattened, thereby adding the given Pair to the Hash.

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

To get back to your question: in the case of an Array, I don't think there is much use for the ,= operation. Before the Great List Refactor, it may have done what you expected. But it would have been inconsistent with other situations, and consistency was deemed more important (because before the Great List Refactor, when something would flatten and when not, was rather arbitrary and many times a source of WAT instead of DWIM).

Serrulation answered 3/2, 2020 at 15:56 Comment(0)
N
2

For those less familiar with Raku, it is easy to flatten any Array with a slip ‘|’ like so:

@a = |@a, :33; 

(at the cost of an extra operator)

Nazi answered 6/2, 2020 at 7:12 Comment(0)
B
0

Array operations are available instead (push, pop, shift, unshift):

In the Raku REPL:

> my @a = 1, 2;
[1 2]
> say @a;
[1 2]
> @a .push: 3;
[1 2 3]
> say @a;
[1 2 3]
> 

Confusingly, operations like .push and .=push give the same result, so the latter is dis-favored:

> @a .=push: 4;
[1 2 3 4]
> say @a;
[1 2 3 4]
> 

The above extant ",=" workarounds are for Arrays. AFAIK no cognate ",=" workaround exists for Lists (e.g. starting from my $b = 1, 2;).

Blynn answered 12/2 at 5:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.