On Tuesday, February 11, 2003, at 04:56 PM, Deborah Ariel Pickett wrote:

But is it OK for a list to be silently promoted to an array when used
as an array? So that all of the following would work, and not just 50%
of them?
(1..10).map {...}
[1..10].map {...}
And somehow related to all this . . .
<snip>
I think some of this is in A2, but not all of it.
Here are some of the answers from my own notes. These behaviors have all been confirmed on-list by the design team:

An @array in list context returns a list of its elements
An @array in scalar context returns a reference to itself (NOTE1)
An @array in numeric (scalar) context returns the number of elements
An @array in string (scalar) context returns a join of its elements

An $arrayref in list context returns an arrayref (NOTE2)
An $arrayref in scalar context returns an arrayref
An $arrayref in numeric (scalar) context returns ??? (NOTE3)
An $arrayref in string (scalar) context returns ???

Note that that's pretty consistent with how it works now.

(NOTE1): This is the big change. It's what allows us to treat arrays as objects, and call methods on them like @array.length. I don't think anyone will argue that's not a good thing.

(NOTE2): Note that this is a non-change. If we changed it so that an arrayref flattened itself in array context, you could never have complex data structures, because [[1,2],[3,4]] would always be the same as [1,2,3,4].

(NOTE3): I have not been able to find explicitly confirmed behaviors for these two. It has been implied that they return $arrayref.length and $arrayref.string (or whatever those methods are called). Maybe.


--- List Flattening ---

The confusing behavior is, of course, that the list

(@a,@b,@c)

is seen as being treated differently in different syntactic contexts. In the case of:

sub foo(@p1,@p2,@p3);

&foo(@a,@b,@c);

the arrays @a, @b, and @c are NOT flattened, but are passed as @p1, @p2, and @p3. Likewise, in:

my(@d,@e,@f) := (@a,@b,@c);

the same is true. But in ALL other circumstances, like

my(@d,@e,@f) = (@a,@b,@c);

an array in list context simply returns it's elements, such that @d = (@a,@b,@c), @e=(), @f=(). So what's the deal?

My own two-sentence explanation for why this is is that in the first two examples, C<sub> and C<:=>, you're binding one variable to another, NOT dealing with the array-ness of those variables at all. E.G.

@a := @b

makes @a refer to the same array object as @b refers to, whereas

@a = @b

simply says to copy all elements _contained within_ @b into @a. So it's not that arrays are behaving differently in different situations, because they're NOT... the same rules always apply. It's just that C<sub> and C<:=> are specific, binding-style operations... they do the same thing for scalar variables, too.

There, how convincing did that sound?

MikeL



Reply via email to