On 2021-01-19 2:18 p.m., Brian Duggan wrote:
Hi Folks,
I ran into this situation today, which seems counterintuitive:
my @one = 1,2,3;
my @two = 4,5,6;
my @both = @one,@two;
my @first = @both[0];
say @one.raku;
say @first.raku;
output:
[1, 2, 3]
[[1, 2, 3],]
I was expecting @first and @one to be the same.
I discovered that I could instead write either of these --
my (@first) = @both[0];
my @first := @both[0];
or I could change the @both assignment to be
my @both := @one, @two;
..but I wonder if there's an idiomatic approach -- or
way of thinking about this -- that makes this flow more
intuitive.
thanks
Brian
Arrays always containerize their values with Scalar ("itemize"). This
means that when they contain arrays as values, each array will get
treated like a singular value that happens to be an Array instead of an
array of values like they normally would elsewhere.
Lists keep their values' containers as-is. These are what the , operator
returns by default, so one way to leverage containers here is to bind to
@both like you already discovered:
my @both := @one, @two;
Another is to type @both as a List and assign:
my @both is List = @one, @two;
But List lacks some of the luxuries Array provides over it, such as
mutability and typed values. What I'd do here is decontainerize @both[0]
with the <> postfix operator so @both's Array typing can be kept:
my @first = @both[0]<>;