On Oct 13, 9:40 am, mike.j...@nethere.com (Mike McClain) wrote:
> On Wed, Oct 13, 2010 at 08:33:57AM +0200, Shlomi Fish wrote:
>
> <snip>
>
> > On Wednesday 13 October 2010 06:39:03 Mike McClain wrote:
> > > Why do @arrays and @seconds not have the same number of elements?
> > >     my @arrays =
> > >         map
> > >         { @{ $HoAoA{$_} } [ 0..$#{ $HoAoA{$_} } ] }
> > >         keys %HoAoA ;
>
> > This is equivalent to:
> > map { @{$HoAoA{$_} } } keys(%HoAoA);
>
> > Which flattens all the arrays into one big list. It can be written better 
> > as:
> > map { @$_ } values(%HoAoA);
>
> Thanks I hadn't seen that.
>
> > >     my @seconds =
> > >         map  { @{ $HoAoA{$_} } [ 0..$#{ $HoAoA{$_} } ]->[1] }
> > >         keys %HoAoA ;
>
> > That's wrong. What it does is create an array, evaluate it in scalar context
> > and then trying to use it as an array refand extract the second element. 
> > Doing
> > @{$array_re...@indices]->[$idx] is a strange construct which makes no sense.
>
> It's right because it complies and executes with no errors.
> It's only wrong because it doesn't give me what I wanted.
> What I still don't understand is why it gives me what it does.
>

It's easier to understand what went wrong by reviewing
the arrow operator (see: perlref)
            ...
            $arrayref->[0] = "January";   # Array element
            $hashref->{"KEY"} = "VALUE";  # Hash element
            $coderef->(1,2,3);            # Subroutine call

        The left side of the arrow can be any expression
        returning  a reference, including a previous deref...
                          ^^^^^^^^^^

and the comma operator (see: perlop)

    Binary "," is the comma operator. In scalar context it
    evaluates its left argument, throws that value away,
    then evaluates its right argument and returns that value.
    ...

In your case,  the left side is an array slice which
generates  a list of values. Because the context is
scalar, the comma operator reduces the expanded
slice list down to [ qw/bc1 bc2/] for the 2nd key for
instance. That just  happens to be a reference so
the arrow operator is happy.  Ditto for the first key
too:

     1st key:     [qw/ab1 ab2/]->[1]    ---> ab2
     2nd key:    [qw/bc1 bc2/ ]->[1]    --->  bc2



A simpler pair of examples might help:

 # ok because the comma op reduces the slice to a ref
 perl -Mstrict -wle "my @a=([1,2],[3,4]);print @a[0..$#a]->[1]"
 4

 # fails because the last element isn't a ref
perl -Mstrict -wle "my @a=([1,2],'foo');print @a[0..$#a]->[1]"
Can't use string ("foo") as an ARRAY ref while "strict refs" ...
.

--
Charles DeRykus


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to