[perl] ハッシュのスライスと多次元ハッシュのエミュレーション

XML::Simpleのコードを読んでいると以下の様な表現が頻繁に出てきました。問題は8行目なのですが、ハッシュをリストコンテキストで扱っているのですが、初めて見る表現で、調べるのにも少し手こずったのでメモしておきます。

#!/usr/bin/perl

use Perl6::Say;
use YAML;

my @keys = qw(key1 key2);
my @vals = qw(val1 val2);
@dic{@keys} = @vals;   # 問題の行
say Dump \%dic;

# 出力は以下のようになります
# ---
# key1: val1
# key2: val2

結論から言えば、これはハッシュのスライスと呼ばれる表現で、配列のスライスと同様にハッシュの部分要素群を一度に扱う事ができます。上記の例では@が多数出てきて紛らわしいのですが、解り易く書くと以下のようになります。

#!/usr/bin/perl

use Perl6::Say;
use YAML;

my @keys = qw(key1 key2);
my @vals = qw(val1 val2);
@dic{'key1', 'key2'} = @vals;   # 問題の行
say Dump \%dic;

このようにハッシュに対して@とブレース内でのキーを指定すると、ハッシュのスライスが扱えます。違和感があったのはハッシュをリストコンテキストで扱いながら、キーを同時に書いていた事なのですが、恥ずかしながら単純に知らないだけでした。それにしても、これは便利ですね。ちなみにpythonの辞書では使えません。残念です。

ところで紛らわしい事にハッシュの複数キーを扱う表現があります。例えば以下のコードを見て下さい。

#!/usr/bin/perl

use Perl6::Say;
use YAML;

my %scores;
$scores{'taichino', 'math'} = 60;
$scores{'taichino', 'english'} = 40;
$scores{'mamino', 'math'} = 50;
$scores{'mamino', 'english'} = 80;

say $scores{'taichino', 'math'};   # 60
say $scores{'mamino', 'english'};  # 80

違いはハッシュのプリフィックスが@では無く$です。プログラミングPerlによるとこれは、多次元ハッシュのエミュレーションと呼ばれているようです。複数キーに対して値をマッピングしているので、確かに疑似多次元ハッシュとして使えますが、現在は使われていないようです。紛らわしいですね。

というわけで、まとめは以下になります。

  • ハッシュのスライス
    @hash{key1,key2…}
  • 多次元ハッシュのエミュレーション
    $hash{key1, key2…}

ハッシュのスライスは便利なのでガンガン使って行きたいですね。

Leave a Reply

Your email address will not be published. Required fields are marked *