Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl incompatibility issue with each in a hash of hashes - 5.14 → 5.8.8

Tags:

perl

The following code works fine with Active Perl 5.14.2:

my %hzones = ();
#%hzones= (
#    'zone1' =>  {
#                  'ns1' => 'ip1',
#                  'ns1' => 'ip2',
#                  },
#    'zone2' =>  {
#                  'ns1' => 'ip1',
#                  'ns2' => 'ip2'
#                  }
#);

foreach my $k1 ( keys %hzones ) {
    debug("# $k1",$d); 
    while ( my ($key, $value) = each($hzones{ $k1 }) ) { # Problem is here   217 
        while ( my ($nsname, $nsip) = each(%$value) ) { 
            debug("## $nsname , $nsip",$d);
    }
    # Creation de la zone et ajout dans infoblox
    $session->add(createZone($k1)) or error("Add zone for ".$k1." failed: ", 
        $session->status_code(). ":" .$session->status_detail());
    }
}

Now, if I try to use this code on RedHat 5.3 with Perl 5.8.8, I have the following error:

Type of arg 1 to each must be hash (not hash element) at
  ./migration-arpa.pl line 217, near "}) "
Execution of ./migration-arpa.pl aborted due to compilation
  errors.

Question: How do I fix this error? How do I traverse my hashtable?

like image 581
Yohann Avatar asked Jun 11 '12 11:06

Yohann


2 Answers

What Quentin said, but you could try replacing

each($hzones{ $k1 })

with

each(%{$hzones{ $k1 }})

which dereferences the hash ref.

like image 85
Qtax Avatar answered Nov 04 '22 13:11

Qtax


The ability to do pass a reference to each (each($hzones{ $k1 })) was introduced in 5.14.0. Before that, one had to pass a hash (each(%{ $hzones{ $k1 })). That still works, and it will continue to work.

So, to be backwards compatible, use

each(%{ $hzones{ $k1 })

instead of

each($hzones{ $k1 })

Note: Passing a reference to each is marked as experimental, and I consider it buggy since it doesn't work with all hashes.

like image 20
ikegami Avatar answered Nov 04 '22 15:11

ikegami