简体   繁体   English

复合哈希是否有Hash :: Util替代方案?

[英]Is there a Hash::Util alternative for compound hashes?

I have a compound hashref as follows 我有一个复合hashref如下

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

Hash::Util::lock_hashref_recurse($ch) does not effectively lock these values.. Hash::Util::lock_hashref_recurse($ch)无法有效锁定这些值。

@{$ch->{k1}}[0]->{k} = 'New value'; is allowed ! 被允许 ! How do i lock such a hashref completely ? 我如何完全锁定这样的hashref?

According to the documentation : 根据文件

This method only recurses into hashes that are referenced by another hash. 此方法仅递归到另一个哈希引用的哈希。 Thus a Hash of Hashes (HoH) will all be restricted, but a Hash of Arrays of Hashes (HoAoH) will only have the top hash restricted. 因此,散列哈希(HoH)将全部受到限制,但哈希散列数组(HoAoH)将仅限制顶部散列。

And you have a Hash of Arrays of Hashes 你有哈希哈希数组

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 itself provides you a low-level function that you can replicate in Perl without XS functionality: ie lock_hash / lock_hashref . Hash::Util本身为您提供了一个低级函数,您可以在没有XS功能的Perl中进行复制:即lock_hash / lock_hashref The rest of functionality you need is a simple hash traversal and can be easily implemented manually. 您需要的其余功能是简单的哈希遍历,可以轻松地手动实现。 Traverse through nested references while keeping list of visited ones and list of found hashes and then run loop over that found list with lock_hashref . 遍历嵌套引用,同时保持已访问的列表和已找到的哈希列表,然后使用lock_hashref在找到的列表上运行循环。

There is Const::Fast , which is able to make any Perl variable completely read-only. Const :: Fast ,它可以使任何Perl变量完全只读。

You won't get the die-on-read behaviour of Hash::Util when you try to read a non-legal key though. 当您尝试读取非合法密钥时,您将无法获得Hash :: Util的读取行为。

What about Readonly ? Readonly怎么样?

Eg 例如

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";

gives

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

Note that %h3 is a hash, not a hashref. 请注意, %h3是哈希值,而不是hashref。 Hashrefs don't work well with Readonly: 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";

gives

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM