How do I use `lock_hash_recurse` in Perl?

邮差的信 提交于 2019-12-10 16:07:43

问题


In continue to the discussion here, I'm havind some trouble with lock_hash_recurse as illustrated below:

#!/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."

From what I can tell, reftype returns undef... is that a bug in lock_hash_recurse (maybe that's why it isn't exported?...)


回答1:


It is a bug in Hash::Util. The code says:

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
}

but should be:

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
}

The problem is that Scalar::Util::reftype returns undef, not an empty string. A patch has been sent to p5p. It doesn't look like Hash::Util is a dual-life (in core and CPAN) module, so you would have to upgrade to a version of Perl 5 with it fixed. I would suggest either patching the code yourself or writing your own version.

If you write your own version, do not use Internals::SvREADONLY (user level stuff shouldn't use the stuff in the Internals package). Use the Readonly::XS module instead.



来源:https://stackoverflow.com/questions/3727619/how-do-i-use-lock-hash-recurse-in-perl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!