http://qs321.pair.com?node_id=761721


in reply to Re: foreach doesn't select array element
in thread foreach doesn't select array element

But shouldn't the foreach() have selected the first array element? If I have a simple array (anna, beth, christie, denise) and pass this @array to foreach, it returns the values. Well, @$fildref3 is a simple array, so when I pass it to foreach(), I expect it to return the members of this array, which is either an array of scalar pairs or the refs to these (in code example 2). I fail to understand why this doesn't work (simulated dump output):
\@arr = [ 1, 2, 3, [ anna, beth, christie, denise ], ] foreach my girl (@$arr[3]) { print "$girl\n"; }

This is what I try to do. Dump doesn't show:

\@arr = [ 1, 2, 3, \[ anna, beth, christie, denise ], ]

(Note the ref marker in front of the girl array.)

If I understand correctly, the @{} is needed to deref the array ref. But Dump shows me it's an ordinary array, like in my first simple array example in this post.

Thanks for helping out...

Replies are listed 'Best First'.
Re^3: foreach doesn't select array element
by ELISHEVA (Prior) on May 04, 2009 at 14:37 UTC

    Your confusion may be coming from the order in which @ and [3] are being handled. @ first converts $fldref from an array reference into an array. Then it lets you use normal array element syntax, @$fldref[3], to access its elements. In other words, @$fldref[3] is equivalent to $fldref->[3].

    You might be able to see this more clearly if we replace $fldref->[3] with a variable, like this:

    my $aVars= [ ["\$a", "Tarina Babarista, pienest{ elefantista"], ["\$s", "(26'34); orkestroitu"], ["\$d", "Poulenc, Francis"], ["\$g", "Brunhoff, Jean de "], ["\$h", "P|ysti, Lasse"], ["\$j", "Fran*8aix, Jean"], ]; my $fldref= [ 500, 0, 0, $aVars ];

    $fldref->[3] is $aVars, a reference to an array and not the dereferenced array, @$aVars. So when you loop on foreach (@$fldref[3]) you are really looping on foreach($fldref->[3]) which is just a loop over the single element $aVars. That is why you dump only once inside the foreach loop and see the $aVars array as a whole when you dump it rather than the individual elements of $aVars, each dumped separately.

    If you want to loop on the contents of $fldref->[3] you have to dereference it yet again and do @{$fldref->[3]} or @{@fldref[3]}. This works as expected:

    foreach my $tmp (@{$fldref->[3]}) { print "$tmp: <@$tmp>\n"; } #outputs ARRAY(0x814ec28) <$a Tarina Babarista, pienest{ elefantista> ARRAY(0x81e652c) <$s (26'34); orkestroitu> ARRAY(0x81e64fc) <$d Poulenc, Francis> ARRAY(0x81e5a4c) <$g Brunhoff, Jean de > ARRAY(0x81f236c) <$h P|ysti, Lasse> ARRAY(0x81f239c) <$j Fran*8aix, Jean>

    Hope that helps, beth

Re^3: foreach doesn't select array element
by Crackers2 (Parson) on May 04, 2009 at 17:20 UTC
    I think you may be confused about Dumper output, and perhaps about what's actually in your arrays. In your first example:
    \@arr = [ 1, 2, 3, [ anna, beth, christie, denise ], ]
    the fourth element in your array is an array ref, not an array. You can only store scalars in an array, so the only way to store an array in another array is to store a reference. The output you show in the second part:
    \[ anna, beth, christie, denise ],
    would actually mean a reference to a reference to an array.
Re^3: foreach doesn't select array element
by AnomalousMonk (Archbishop) on May 05, 2009 at 15:15 UTC
    december:

    I think you are also confused about Perl array and anonymous array syntax. The statement
        my @array = ('a', 'b', 'c');
    constructs a list which is then used to initialize an array. The statement
        my $array_ref = ['a', 'b', 'c'];
    constructs an anonymous array and returns a scalar reference to the array that is then used to initialize a scalar. See discussions of the  [ ] anonymous array constructor in perlref and perlreftut.

    Consider the following examples:

    >perl -wMstrict -MData::Dump=dump -le "my \@arr = [ 1, 2, 3, [ 'anna', 'beth', 'christie', 'denise' ], ]; dump @arr; " syntax error at -e line 1, near "my \" Global symbol "@arr" requires explicit package name at -e line 1. Global symbol "@arr" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors. >perl -wMstrict -MData::Dump=dump -le "my @arr; \@arr = [ 1, 2, 3, [ 'anna', 'beth', 'christie', 'denise' ], ]; dump @arr; " Can't modify reference constructor in scalar assignment ... near "];" Execution of -e aborted due to compilation errors. >perl -wMstrict -MData::Dump=dump -le "my @arr = [ 1, 2, 3, [ 'anna', 'beth', 'christie', 'denise' ], ]; dump @arr; print scalar @arr; " [1, 2, 3, ["anna", "beth", "christie", "denise"]] 1 >perl -wMstrict -MData::Dump=dump -le "my @arr = ( 1, 2, 3, [ 'anna', 'beth', 'christie', 'denise' ], ); dump @arr; print scalar @arr; " (1, 2, 3, ["anna", "beth", "christie", "denise"]) 4
    Neither of the first two examples compile at all.

    The third example initializes an array with a single element (as shown by the
        print scalar @arr;
    statement), a scalar that is a reference to an anonymously constructed array.

    The fourth example initializes an array with four elements (one of which happens to be a reference to yet another anonymous array).