5

我有一个复合 hashref 如下

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

Hash::Util::lock_hashref_recurse($ch)没有有效地锁定这些值..

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

4

5 回答 5

5

根据文档

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

你有一个哈希数组的哈希

于 2013-08-05T11:36:03.977 回答
2
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 …
于 2013-08-05T14:06:37.990 回答
1

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

于 2013-08-05T12:39:36.067 回答
0

Const::Fast,它能够使任何 Perl 变量完全只读。

但是,当您尝试读取非法密钥时,您不会得到 Hash::Util 的读取时死亡行为。

于 2013-08-05T15:02:48.150 回答
0

只读呢?

例如

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是一个哈希,而不是一个 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'
于 2013-12-25T06:24:18.197 回答