Thanks for the quick reply. Larry Wall wrote: > On Tue, Jul 28, 2009 at 09:24:40PM +0200, Moritz Lenz wrote: > : sub W () { substr(eval('want'), 0, 1) } > : ... > : > : # line 560: > : { > : my @a; > : my @z = (@a[0] = W, W); > : #?rakudo 2 todo 'want function' > : is(@a, 'L', 'lhs treats @a[0] as list'); > : is(@z[0], 'L', 'lhs treats @a[0] as list'); > : ok(!defined(@z[1]), 'lhs treats @a[0] as list'); > : } > : > : > : This tests that > : 1) both calls to want() are in list context > : 2) @a[0] gets only the return value of the first call to W() > : 3) @z[0] gets the same thing > : 4) There's no item for @z[1] > : > : Somehow I think this test (and many similar tests) are dead wrong. > : Here's why: > : > : Either it's parsed as '@a[0] = (W, W)' (list assignment), then @a should > : get both elements, and so should @z. > > Not according to S03, at least by one reading. @a[0] as a scalar > container only wants one item, so it only takes the first item off > the list, and the list assignment produces a warning on the second > because it's discarded. Since an assignment returns its left side, > only one element is available to @z from @a[0].
So it's parsed like a list assignment, but list-assigning to a scalar container doesn't promote the whole RHS to a Capture (or whatever it ends up being) as it would do in the case of item assignment, but takes one item off. OK. I guess when I initialize @a[0] = [] it's the same, because then @a[0] is still a scalar, right? Only when I wrote @a[0] := [] I'd get all items in @a[0]. > : Or it's parsed as '(@a[0] = W), W' (item assignment), then the first > : call should be in item context, and the second one in list context, and > : @z should still get both items. > > It's not parsed like that, because only $x, $$xref, $($xref) and such > are allowed targets for item assignment. Basically, it has to start > with a $ sigil and not do anything fancy like subscripting. However, > if you say > > @z = $x = $a, $b; > > it parses as @z = ($x = $a), $b and $b ends up in @z[1] but not > in $x, which only gets $a. > > : Right? Or am I completely missing something important here? > > To get all the elements into $x you'd have to say > > @z = $x = ($a, $b); > > and @z[0] would be ($a,$b) with some type or other, whatever was > returned by the parens, quite possibly Parcel (that is, List of Thunk > or some such). Ok, that makes sense to me. > : My current plan is to write such tests as > : > : sub l { 1, 2 } # return a short list > : { > : my @a; > : my @z = (@a[0] = l(), l()); > : is @a[0].elems, 4, '@a[0] = treats LHS as list' > : is @z.elems, 4, '... and passes all elements on the right'; > : } > : > : Does this look sane, and match your understanding of assignment? > > Yes, but no. @z.elems and @a[0].elems should both be 1, I suspect. > I wish we had a way of trapping and testing warnings too so we could > see that 3 elements were discarded by the inner list assignment.. > > Larry Cheers, Moritz