How to use `lock_hash_recurse` in Perl?

To continue the discussion here , I have problems with lock_hash_recurse , as shown 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 ... this is an error in lock_hash_recurse (maybe why is it not being exported?)

+4
source share
1 answer

This 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. The patch was sent to p5p. It doesn't look like Hash::Util is a double-life module (in the kernel and CPAN), so you have to update the version of Perl 5 with the corrected one. I suggest either fixing the code yourself, or writing your own version.

If you are writing your own version, do not use Internals :: SvREADONLY (the user level should not use material in the Internals package). Use Readonly::XS .

+6
source

All Articles