rubyでハッシュのハッシュのハッシュとかを簡単に作る方法
Perlだと、特に宣言なしに、
とか出来るのに Ruby だといちいち Hash.new() など宣言しなくてはならず不便です!
しかし以下のおまじないを唱えると、ハッシュのハッシュのハッシュとかを一気に宣言できちゃって便利ったらありゃしません。
というのが使い方で、とっても便利ですね、いろんな場面で使えそうです!
以下は、なんでーそうなるの?と個人的に追っていった考察メモです。こんな考察するなんて私って粘着質ですね。
まず、Hash.newの引数にブロック(上の例でいうと{|h,k| h[k]=Hash.new(&h.default_proc)})を与えるってどういうこと?についてですが、
rubyオンラインマニュアルに
値が設定されていないハッシュ要素を参照するとその都度ブロックを実行し、その結果を返します。ブロックにはそのハッシュとハッシュを参照したときのキーが渡されます。
とあります。
つまり
my_hash = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) }
my_hash[:aaa] = 'bbb'
とした時点で、
my_hash[:aaa] = Hash.new()
my_hash[:aaa] = 'bbb'
もやってくれるし、さらに一階層深いハッシュが作られた場合にHash.new()をする準備、例えば以下のようなこと
my_hash[:aaa][:aaa2] = Hash.new()
をしてくれる準備も整ってるよ、という状態になります。うまく言えないけど、そんな感じ。
上記の
&h.default_proc
という部分が
{|h,k| h[k]=Hash.new(&h.default_proc) }
を指しているから再帰的に処理される訳ですね。うまく言えてないなあ。でもそんな感じ。
これ考えた人天才だわ。
参考サイト
http://www.ruby-forum.com/topic/130324
http://snippets.dzone.com/posts/show/4146
【広告】
$a{'size'}{'upperbody'}{'chest'} = 100;
とか出来るのに Ruby だといちいち Hash.new() など宣言しなくてはならず不便です!
しかし以下のおまじないを唱えると、ハッシュのハッシュのハッシュとかを一気に宣言できちゃって便利ったらありゃしません。
my_hash = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)}
my_hash[:size][:upperbody][:chest] = 100
my_hash[:size][:egg] = 'XL'
my_hash =>
{:size=>{:upperbody=>{:chest=>100}, :egg=>"XL"}}
というのが使い方で、とっても便利ですね、いろんな場面で使えそうです!
以下は、なんでーそうなるの?と個人的に追っていった考察メモです。こんな考察するなんて私って粘着質ですね。
まず、Hash.newの引数にブロック(上の例でいうと{|h,k| h[k]=Hash.new(&h.default_proc)})を与えるってどういうこと?についてですが、
rubyオンラインマニュアルに
値が設定されていないハッシュ要素を参照するとその都度ブロックを実行し、その結果を返します。ブロックにはそのハッシュとハッシュを参照したときのキーが渡されます。
とあります。
つまり
my_hash = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) }
my_hash[:aaa] = 'bbb'
とした時点で、
my_hash[:aaa] = Hash.new()
my_hash[:aaa] = 'bbb'
もやってくれるし、さらに一階層深いハッシュが作られた場合にHash.new()をする準備、例えば以下のようなこと
my_hash[:aaa][:aaa2] = Hash.new()
をしてくれる準備も整ってるよ、という状態になります。うまく言えないけど、そんな感じ。
上記の
&h.default_proc
という部分が
{|h,k| h[k]=Hash.new(&h.default_proc) }
を指しているから再帰的に処理される訳ですね。うまく言えてないなあ。でもそんな感じ。
これ考えた人天才だわ。
参考サイト
http://www.ruby-forum.com/topic/130324
http://snippets.dzone.com/posts/show/4146
【広告】