如何在Perl中使用`lock_hash_recurse`?

Dav*_*d B 4 perl hash locking

继续在这里讨论,我遇到了一些麻烦,lock_hash_recurse如下图所示:

#!/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."
Run Code Online (Sandbox Code Playgroud)

从我所知道的,reftype返回undef...是一个错误lock_hash_recurse(也许这就是为什么它不会被导出?...)

Cha*_*ens 6

这是一个错误Hash::Util.代码说:

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
}
Run Code Online (Sandbox Code Playgroud)

但应该是:

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
}
Run Code Online (Sandbox Code Playgroud)

问题是Scalar::Util::reftype返回undef,而不是空字符串.补丁已发送到p5p.它看起来不像Hash::Util是双生命(在核心和CPAN中)模块,因此您必须升级到Perl 5的版本并修复它.我建议您自己修补代码或编写自己的版本.

如果您编写自己的版本,请不要使用Internals :: SvREADONLY(用户级别的东西不应该使用Internals包中的东西).请改用Readonly::XS模块.

  • 看起来它是核心而不是双重生命,所以我们可以做到报告它到p5p.如果您想要修复您正在使用的Perl版本,则必须自行修改它.另一种可能性是使"Hash :: Util"具有双重生命力.我将在p5p上提出这个问题. (2认同)
  • 哎呀,看起来这已经在[blead](http://perl5.git.perl.org/perl.git/commitdiff/1e6ffe563afa06bebdef40d37cf4bdae8ac5f14d)中修复了,但它没有进入Perl 12.2.您可以将相同的修补程序应用于您的版本. (2认同)