2010-09-16 8 views
4

Dans continuer la discussion here, je havind quelques problèmes avec lock_hash_recurse comme illustré ci-dessous:Comment utiliser `lock_hash_recurse` en Perl?

#!/usr/bin/perl 

use strict; 
use warnings; 
use Data::Dumper; 
use Hash::Util qw (lock_keys); 

my $hashref = {A=>1, B=>{CC=>22, DD=>33}}; 

lock_keys(%{$hashref}); # this is OK 
Hash::Util::lock_hash_recurse(%{$hashref}); # this fails: "Use of uninitialized value in string eq at /usr/lib/perl/5.10/Hash/Util.pm line 153." 

D'après ce que je peux dire, reftype retours undef ... est qu'un bogue dans lock_hash_recurse (peut-être pourquoi ce n'est pas exporté? ...)

Répondre

6

C'est un bug dans Hash::Util. Le code dit:

sub lock_hashref_recurse { 
    my $hash = shift; 

    lock_ref_keys($hash); 
    foreach my $value (values %$hash) { 
     if (reftype($value); eq 'HASH') { 
      lock_hashref_recurse($value); 
     } 
     Internals::SvREADONLY($value,1); 
    } 
    return $hash 
} 

mais devrait être:

sub lock_hashref_recurse { 
    my $hash = shift; 

    lock_ref_keys($hash); 
    foreach my $value (values %$hash) { 
     my $type = reftype($value); 
     if (defined $type and $type eq 'HASH') { 
      lock_hashref_recurse($value); 
     } 
     Internals::SvREADONLY($value,1); 
    } 
    return $hash 
} 

Le problème est que Scalar::Util::reftype retours undef, pas une chaîne vide. Un patch a été envoyé à p5p. Il ne semble pas que Hash::Util soit un module dual-life (dans le noyau et le CPAN), donc vous devriez passer à une version de Perl 5 avec ce correctif. Je suggère soit de patcher le code vous-même ou d'écrire votre propre version.

Si vous écrivez votre propre version, n'utilisez pas Internals :: SvREADONLY (les choses au niveau de l'utilisateur ne devraient pas utiliser les trucs dans le paquet Internals). Utilisez plutôt le module Readonly::XS.

+0

+1 Merci. Y a-t-il un moyen de régler rapidement cela? contacter l'auteur ou quelque chose? Je ne veux pas commencer ma propre version ... –

+2

On dirait que c'est dans le noyau et pas dual-lifed, donc le signaler à p5p est tout ce que nous pouvons faire. Si vous voulez un correctif sur la version de Perl que vous utilisez, vous devrez le modifier vous-même. Une autre possibilité serait de rendre 'Hash :: Util' dual-lifed. Je vais soulever ça sur p5p. –

+2

Oups, on dirait que cela a déjà été corrigé dans [blead] (http://perl5.git.perl.org/perl.git/commitdiff/1e6ffe563afa06bebdef40d37cf4bdae8ac5f14d), mais cela ne l'a pas fait dans Perl 12.2. Vous pouvez simplement appliquer le même correctif à votre version. –

Questions connexes