use strict;
use warnings;
use Data::Dumper;
print Dumper {
one => sub { return 1 }->(),
two => sub { return 2 }->(),
hoge => sub { return () }->(),
fuga => sub { return () }->()
};
便宜上、今は関数は無名関数にしています。
関数の返り値を使って、ハッシュのリファレンスを作りたい時に、上記のようなケースになった場合、下記のデータ構造がDumpされます。
$VAR1 = {
'one' => 1,
'hoge' => 'fuga',
'two' => 2
};
hogeというキーにfugaという値が代入されてしまっていて、意図したデータ構造になりません。
意図したデータ構造は以下のような形です。
$VAR1 = {
'one' => 1,
'fuga' => undef,
'hoge' => undef,
'two' => 2
};
値を代入するために呼び出す関数を修正しない限りは、予め初期値を入れる他ないのでしょうか?
print Dumper {
one => sub { return 1 }->() || undef,
two => sub { return 2 }->() || undef,
hoge => sub { return () }->() || undef,
fuga => sub { return () }->() || undef
};
もっと良い解決方法というか、こうやったらいいよっていう方法があったら教えてください。
よろしくお願いします。
ちょっと面倒ですけど、強制的にスカラーコンテキストにするというのはいかがでしょうか。
use strict; use warnings; use Data::Dumper; print Dumper { one => scalar(sub { return 1 }->()), two => scalar(sub { return 2 }->()), hoge => scalar(sub { return () }->()), fuga => scalar(sub { return () }->()) };
なんというか、書き方がマズイだけのきがするよ。
print Dumper { one => sub { return 1 }->(), two => sub { return 2 }->(), hoge => sub { return () }->(), fuga => sub { return () }->() };
これは
print Dumper { 'one' , sub { return 1 }->(), 'two' , sub { return 2 }->(), 'hoge' , sub { return () }->(), 'fuga' , sub { return () }->() };
と等価で、関数の結果を評価すると
print Dumper { 'one' , 1, 'two' , 2, 'hoge' , (), 'fuga' , () };
となって、同じく
print Dumper { 'one' , 1, 'two' , 2, 'hoge' , 'fuga' };
と等価なわけだ。
ハッシュの生成時って単にリストを渡してるだけだから
どれがキーでどれが値かは全く考慮しない。
これじゃあ最初の出力になって当然だよね。
ちなみに、
print Dumper { 'one' , sub { return 1 }->(), 'two' , sub { return 2 }->(), 'hoge' , sub { return () }->() }
これだと要素が奇数だといって怒られるんじゃ無いかな。
関数の返す値がどういう意味を持っているかにもよるけど
print Dumper { one => sub { return 1 }->(), two => sub { return 2 }->(), hoge => sub { return [] }->(), fuga => sub { return [] }->() };
と、元からスカラー値を返すように確定させるか、
my %hash = (); $hash{one} = sub { return 1 }->(); $hash{two} = sub { return 2 }->(); $hash{hoge} = sub { return () }->(); $hash{fuga} = sub { return () }->(); print Dumper \%hash;
とやるほうが間違いが起こらないと思うけどね。
なるほど!記法を変えてみるとよくわかるんですね。なぜ、あのようなデータが出来上がるのかがよくわかりました。ありがとうございます。
ありがとうございます。同じアドバイスをTwitterでもいただきましたが、今回のケースではスカラー値が欲しいので、ご教授いただいた方法は適切でした。