复合散列是否有Hash::Util替代方案



我有一个复合hashref,如下

my $ch = {
    k1 => [ { k=>1 }, { m=>2 } ],
    k2 => [ { l=>90}, ... ],
};

Hash::Util::lock_hashref_recurse($ch)不会有效地锁定这些值。。

允许@{$ch->{k1}}[0]->{k} = 'New value';!如何完全锁定这样的hashref?

根据文档:

此方法只递归到另一个哈希引用的哈希中。因此,散列的散列(HoH)将全部受到限制,但散列的数组的散列(HoAoH)将只限制顶部散列

你有一个散列数组的散列

use strictures;
use Hash::Util qw(lock_hash);
use Data::Visitor::Callback qw();
my $ch = {
    k1 => [{k => 1}, {m => 2}],
    k2 => [{l => 90},],
};
Data::Visitor::Callback->new(
    hash => sub {
        lock_hash %{ $_ }; 
        return $_;
    }
)->visit($ch);
$ch->{k1}[0]{k} = 'New value';
__END__
Modification of a read-only value attempted at …

Hash::Util本身为您提供了一个低级函数,您可以在没有XS功能的情况下在Perl中复制该函数:即lock_hash/lock_hashref。您需要的其余功能是一个简单的散列遍历,并且可以很容易地手动实现。遍历嵌套引用,同时保留访问的引用列表和找到的哈希列表,然后使用lock_hashref在找到的列表上运行循环。

有Const::Fast,它可以使任何Perl变量完全只读。

不过,当你试图读取非合法密钥时,你不会得到Hash::Util的死后读取行为。

Readonly怎么样?

例如

use Readonly;
Readonly my %h3 => (
    k1 => [ { k=>1 }, { m=>2 } ],
    k2 => [ { l=>90}, ],
);
print "old value: '$h3{k1}->[0]->{k}'n";
$h3{k1}->[0]->{k} = 'New value';
print "new value: '$h3{k1}->[0]->{k}'n";

给出

old value: '1'
Modification of a read-only value attempted at readonly.pl line 7

请注意,%h3是一个hash,而不是hashref。Hashrefs不能很好地与Readonly:配合使用

use Readonly;
Readonly my $h2 => {
    k1 => [ { k=>1 }, { m=>2 } ],
    k2 => [ { l=>90}, ],
};
print "old value: '$h2->{k1}->[0]->{k}'n";
$h2->{k1}->[0]->{k} = 'New value';
print "new value: '$h2->{k1}->[0]->{k}'n";

给出

old value: '1'
new value: 'New value'

最新更新