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].
: 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).
: 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