我有一个复合 hashref 如下
my $ch = {
k1 => [ { k=>1 }, { m=>2 } ],
k2 => [ { l=>90}, ... ],
};
Hash::Util::lock_hashref_recurse($ch)
没有有效地锁定这些值..
@{$ch->{k1}}[0]->{k} = 'New value';
被允许 !我如何完全锁定这样的 hashref ?
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 的读取时死亡行为。
只读呢?
例如
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'