perl inbuilt function 'each' may be having a bug

A

al.moorthi

Hi,
This code is not working and assigning values to '' , actually it
shouldn't.
#!/usr/bin/perl
use strict;
use warnings;

my %x= (a=>{a=>1,b=>2}, c=>3);
foreach (0..3) {
my($a,$b) = each %{$x{a}};
print "A = '$a', B = '$b'\n";
}
exit(0);

perl each-bug.pl
OUTPUT IS:
A = 'a', B = '1'
A = 'b', B = '2'
Use of uninitialized value in concatenation (.) or string at each-
bug.pl line 8.
Use of uninitialized value in concatenation (.) or string at each-
bug.pl line 8.
A = '', B = ''
A = 'a', B = '1'
 
M

Mirco Wahab

This code is not working and assigning values to '' , actually it
shouldn't.

It does what it "should", imho.
#!/usr/bin/perl
use strict;
use warnings;

my %x= (a=>{a=>1,b=>2}, c=>3);
foreach (0..3) {

The hash $x{$a} has only 2 elements,
the foreach (0..3) are *more* than this
my($a,$b) = each %{$x{a}};
print "A = '$a', B = '$b'\n";

...
my %x = ( a =>
{ a => 1,
b => 2
},
c => 3
);

for (0 .. keys(%x) - 1) { # implicit "scalar keys(...)"
my ($a, $b) = each %{ $x{a} };
print "A = '$a', B = '$b'\n"
}


Regards

M.
 
G

Gunnar Hjalmarsson

This code is not working and assigning values to '' , actually it
shouldn't.

Why shouldn't it behave in accordance with the documentation? From
"perldoc -f each":
"When the hash is entirely read, a null array is returned in list context"
 
A

anno4000

Hi,
This code is not working and assigning values to '' , actually it
shouldn't.

It works exactly to specification.
#!/usr/bin/perl
use strict;
use warnings;

my %x= (a=>{a=>1,b=>2}, c=>3);
foreach (0..3) {
my($a,$b) = each %{$x{a}};
print "A = '$a', B = '$b'\n";
}
exit(0);

perl each-bug.pl
OUTPUT IS:
A = 'a', B = '1'
A = 'b', B = '2'
Use of uninitialized value in concatenation (.) or string at each-
bug.pl line 8.
Use of uninitialized value in concatenation (.) or string at each-
bug.pl line 8.
A = '', B = ''
A = 'a', B = '1'

Why are you using a two-level hash to demonstrate the behavior? You're
only using the inner hash. Here is a simplified version that behaves
exactly the same:

my %y = ( a => 1, b => 2);

foreach ( 0 .. 3 ) {
my ( $a, $b) = each %y;
print "A = '$a', B = '$b'\n";
}

You are calling each() four times on a hash that has only two key-value
pairs. The documentation says:

When the hash is entirely read, a null array is returned in
list context (which when assigned produces a false (0) value),
and "undef" in scalar context. The next call to "each" after
that will start iterating again. There is a single iterator

That is exactly what's happening. The first two calls act "normally".
The you get one call that leaves $a and $b undefined. Since you are
enforcing evaluation in string context, these look like empty strings.
Finally the iteration starts over and you see the first pair again.

Where is the bug?

Anno
 
M

Mirco Wahab

This code is not working and assigning values to '' , actually it
shouldn't.

It does what it "should", imho.
my %x= (a=>{a=>1,b=>2}, c=>3);
foreach (0..3) {
The whole hash has only 2 elements,
the hashref $x{$a} points to twe
elements, but the foreach (0..3) are
*more* than two.
my($a,$b) = each %{$x{a}};
print "A = '$a', B = '$b'\n";
}
exit(0);

At first, I didn't understand your intention
and posted a irrelevant response (which I
canceled). What I think now what you should
do in order to get along - is sth. like this:

...

my %x = ( a =>
{ a => 1,
b => 2
},
c => 3
);

for ( keys %x ) {
# print the outer hash as it is
print "k=$_, v=$x{$_}\n";

# check if the hash value is a hashref
if( UNIVERSAL::isa $x{$_},'HASH' ) {
# and bump along
while ( my ($a, $b) = each %{ $x{a} } ) {
print "\tA = '$a', B = '$b'\n";
}
}

}

....

Regards

M.
 
M

Mirco Wahab

Mirco said:
while ( my ($a, $b) = each %{ $x{a} } ) {
print "\tA = '$a', B = '$b'\n";
}

WTF!

Must of course read ($_ instead of 'a'):
...
while ( my ($a, $b) = each %{ $x{$_} } ) {
...

Sorry

M.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,205
Messages
2,571,067
Members
47,673
Latest member
MahaliaPal

Latest Threads

Top