2013-08-05 3 views
5

複合ハッシュのためのHash :: Utilの代替手段はありますか?

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

Hash::Util::lock_hashref_recurse($ch)が効果的にこれらの値をロックしない、次のように私は、化合物のハッシュリファレンスを持っているが...

@{$ch->{k1}}[0]->{k} = 'New value';が許可されています!このようなハッシュリファレンスを完全にロックするにはどうすればよいですか? documentationによれば

答えて

5

この方法は、別のハッシュによって参照されるハッシュに再帰します。したがって、ハッシュのハッシュ(HoH)はすべて制限されますが、ハッシュの配列ハッシュ(HoAoH)は、トップハッシュのみが制限されます。すなわちlock_hash/lock_hashref

そして、あなたはハッシュ

の配列のハッシュ
+0

オーケー与え、このようなハッシュをロックする別の方法があります? (Hash :: Util以外) – trinity

1

Hash::Util自体を持っているが、あなたがXS機能なしPerlで複製することができ、低レベルの機能を提供します。必要な残りの機能は単純なハッシュトラバーサルであり、簡単に手動で実装できます。訪問されたもののリストと発見されたハッシュのリストを保持しながら、入れ子にされた参照をたどり、見つけたリストの上でループを実行してlock_hashrefとします。

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 … 
0

Const::Fastがあります。これはPerl変数を完全に読み取り専用にすることができます。

しかし、法的でないキーを読み込もうとすると、Hash :: Utilのダイオンリードの動作が得られません。

0

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

%h3はハッシュではなく、ハッシュ・リファレンスであることを

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

注意を与えます。ハッシュリファレンスは、読み込み専用とうまく動作しません:

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' 
関連する問題