I am trying to put the parameters in a for loop into array of FIXED size. This is what I have been doing (I want to use a array @m of 3 elements):
for (1..19).rotor(3, :partial) -> @m { say @m; } # works, but I cannot specify size of @m
However, all of the following give me errors:
for (1..19).rotor(3, :partial) -> @m[0,1,2] { say @m; }
===SORRY!=== Error while compiling:
Variable '@m' is not declared
------> ).rotor(3, :partial) -> @m[0,1,2] { say ⏏@m; }
for (1..19).rotor(3 => -2) -> @m[0..2] { say @m; }
===SORRY!=== Error while compiling:
Variable '@m' is not declared
------> 1..19).rotor(3 => -2) -> @m[0..2] { say ⏏@m; }
for (1..19).rotor(3 => -2) -> @m[3] { say $_; say @m; }
===SORRY!=== Error while compiling:
Variable '@m' is not declared
------> ).rotor(3 => -2) -> @m[3] { say $_; say ⏏@m; }
So, how should I specify that the array @m must have only 3 elements?
The title of the question mentions destructuring, but that is about taking something apart. For example, we could extract the three elements using it:
for (1..19).rotor(3, :partial) -> [$a, $b, $c] {
}
However, this doesn't seem to actually be a destructuring problem, since the request isn't to break the passed aggregate into its parts, but transform it into a different type of aggregate.
Looking a little further at the question:
I am trying to put the parameters in a for loop into array of FIXED size.
The thing is, rotor
doesn't produce (mutable) Array
s at all. Instead, when writing:
for (1..19).rotor(3, :partial) -> @m {
}
Then @m
is a List
. A List
is immutable (and thus implicitly its size is fixed at creation), so if the intent is that there can be no accidental change of size, that's already a cert. Unfortunately, the ultimate goal wasn't stated.
If really wanting to turn the passed immutable List
into a shaped Array
, there's nothing for it other than to assign it into a new fixed size Array
:
for (1..19).rotor(3, :partial) -> @l {
my @arr[3] = @l;
}
Of course, this is going to blow up if the :partial
leads to leftover elements; one could do:
for (1..19).rotor(3, :partial) -> @l {
my @arr[@l.elems] = @l;
}
To avoid that. However, if the goal as really to ensure that things blow up if there ever are leftover elems, then either a where
:
for (1..19).rotor(3, :partial) -> @m where .elems == 3 {
}
Or, a bit less clearly, a throw-away destructure:
for (1..19).rotor(3, :partial) -> @m [$,$,$] {
}
Would do it.
So the -> @m[3]
is what you want but that's assigning a Signature your anonymous block that's expecting a shaped array and you're passing in a List.
So what I ended up doing may coercing my list into a shaped Array.
for (1..19).rotor(3, :partial).map( { Array.new(:shape(3),$_ ) } ) -> @m[3] { say @m; }
And then it works fine. There's probably a better way to do it though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With