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

Reply via email to