On Fri, 18 Sep 2015 00:51:42 -0700, larry wrote:
> 00:13 < TimToady> m: for (1,2,3).pairs X (4,5,6).pairs -> ($x,$y) { say "$x
> $y" }
> 00:13 <+camelia> rakudo-moar c0e0c9: OUTPUT«This type cannot unbox to a
> native string in block at /tmp/YnA_LhZbRO:1»
It gives a nicer error message now:
➜ for (1,2,3).pairs X (4,5,6).pairs -> ($x,$y) { say "$x $y" };
Too few positionals passed to ''; expected 2 arguments but got 0 in
sub-signature
in block at -e line 1
The reason for the error is that sub-signatures use `.Capture`, and
`List.Capture` turns Pair elements into named arguments:
➜ dd (a => 1, 42, b => 2).Capture;
\(42, :a(1), :b(2))
I too have got bitten by this trap before - it essentially makes it unsafe to
pass lists containing Pair objects to code (think e.g. a third-party module)
that expects arbitrary lists of objects, unless you can ensure that the code
doesn't and never will end up binding the list to a sub-signature (or otherwise
calling `.Capture` on it).
It's IMO also conceptually dubious. A List firmly represents the concept of
"list of positional elements", and I see no compelling conceptual reason why
`.Capture` should second-guess this meaning based on the *type* of the list
elements.
So I can only assume that it works like it does now, for practical reasons -
i.e. because something in core relies, or used to rely, on it working this way.
But what?
Note that flattening things into argument lists *doesn't* suffer from this
issue, because instead of `.Capture` it uses `.FLATTENABLE_LIST` +
`.FLATTENABLE_HASH` which always cleanly treat list elements as positionals and
hash entries as nameds.
Marking this ticket as [@LARRY].