Perlのハッシュのリファレンスについて質問です。


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

もっと良い解決方法というか、こうやったらいいよっていう方法があったら教えてください。
よろしくお願いします。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2011/05/11 18:50:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答2件)

id:MAS3 No.1

回答回数40ベストアンサー獲得回数2

ポイント35pt

ちょっと面倒ですけど、強制的にスカラーコンテキストにするというのはいかがでしょうか。

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 () }->())
};
id:jdg

ありがとうございます。同じアドバイスをTwitterでもいただきましたが、今回のケースではスカラー値が欲しいので、ご教授いただいた方法は適切でした。

2011/05/04 23:55:19
id:b-wind No.2

回答回数3344ベストアンサー獲得回数440

ポイント35pt

なんというか、書き方がマズイだけのきがするよ。

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;

とやるほうが間違いが起こらないと思うけどね。

id:jdg

なるほど!記法を変えてみるとよくわかるんですね。なぜ、あのようなデータが出来上がるのかがよくわかりました。ありがとうございます。

2011/05/06 08:34:33
  • id:jdg
    代入される値(上記の例でいうundef)にこだわりはありません。目的とするデータ構造が壊れるのを避けたいだけです。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません