ハッシュを deep merge してくれる Hash::Merge
2 つのハッシュをマージしたいとき,単純には下記のような方法で動きます。
my %a = ( key1 => 'value_a1', key2 => 'value_a2', ); my %b = ( key1 => 'value_b1', key3 => 'value_b3', ); my %c = (%a, %b); # %c is: # key1 => 'value_b1' # override # key2 => 'value_a2' # key3 => 'value_b3' # merge
というのも,そもそも,
my %a = ( key1 => 'value1', key1 => 'value2', key1 => 'value3', ); # %a is ( key1 => 'value3' )
代入もとの配列に同じキーがあっても上書きしてくれるからです。
でも,
my %a = ( data => { key1 => 'value1', }, ); my %b = ( data => { key2 => 'value2', }, ); my %c = (%a, %b); # %c is: # data => { # key2 => 'value2', # } # (equivalent to %b)
のように,配列の深い階層までマージしてくれるわけではありません。
このようなときに,その名も Hash::Merge を使うと,深い階層も含めてマージしてくれます。
#!/usr/bin/perl use strict; use Hash::Merge; use Data::Dumper; my %a = ( key => 'A', key_a => 'value_a', data => { key1 => 'value1', }, ); my %b = ( key => 'B', key_b => 'value_b', data => { key2 => 'value2', }, ); my %c = %{ Hash::Merge::merge(\%a, \%b) }; print Dumper(\%c);
この結果は,
\%c = { 'key' => 'A', 'key_a' => 'value_a', 'key_b' => 'value_b', 'data' => { 'key1' => 'value1', 'key2' => 'value2', }, };
となります(わかりやすいように出力は変えてありますが)。上書きするべきところは上書きし,マージするべきところはマージしてくれています。引数と戻り値がすべてハッシュのリファレンスになっているところが要注意です。