Subject: | each_kv used on array-of-hashrefs |
Date: | Tue, 10 Mar 2015 12:39:45 -0400 |
To: | bug-Var-Pairs [...] rt.cpan.org |
From: | John Pickard <jep5m [...] virginia.edu> |
Hi,
First, thank you for publishing Var::Pairs - very exciting.
I think I may have identified an issue with using each_kv() as a drop-in
replacement for the built-in each. Here's a test case, the first example is
the way we are currently using each, then there's a version using the
drop-in replacement. The drop-in replacement doesn't work as expected, it
does not appear to iterate over the next hashref element in the arrayref
I did use strict / use warnings and use Var::Pairs qw(each_kv); for all of
these tests.
######## Current with each keyword, need to reset iterators with keys
keyword
my $test3 = [
{ a => 1 },
{ b => 2 },
{ c => 3 },
];
foreach my $hash ( @{$test3} ) {
my ($key, $val) = each %$hash;
keys %$hash;
print "Got $key => $val\n";
}
foreach my $hash ( @{$test3} ) {
my ($key, $val) = each %$hash;
keys %$hash;
print "Got $key => $val\n";
}
######## Drop-in replacement: each_kv does not iterate over the 2nd hash
element in $test3
my $test3 = [
{ a => 1 },
{ b => 2 },
{ c => 3 },
];
foreach my $hash ( @{$test3} ) {
my ($key, $val) = each_kv %$hash;
print "Got $key => $val\n";
}
foreach my $hash ( @{$test3} ) {
my ($key, $val) = each_kv %$hash;
print "Got $key => $val\n";
}
########### END
It looks like in the second loop through the first foreach, each_kv is
still working on the first $hash in @$test3. Actually, I can verify that
statement by adding a second key/value to the first hash in @$test:
#### Add second key/value
my $test3 = [
{ a => 1, a1 => 3 },
{ b => 2 },
{ c => 3 },
];
foreach my $hash ( @{$test3} ) {
my ($key, $val) = each_kv %$hash;
print "Got $key => $val\n";
}
### Output
Got a => 1
Got a1 => 3
Use of uninitialized value $key in concatenation (.) or string at ...
### Output from using each and keys to reset the iterator:
Got a => 1
Got b => 2
Got c => 3
Best,
John