我有一个复合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'