みんなのちからになりたい

コピペでブログラムつくっていきたい

hashの初期値

Hashのこんな使い方 #Ruby - Qiita

hashに初期値入れられるのは知ってたけどこんな便利なことできるって知らなかった。
すごい便利。試してみる。

val = Hash.new do |hash, key|
  p "haitta!!"
end

p val_a: val["a"] = "a1"
p val_b: val["b"]
p val_a: val["a"] = "a2"
p val_b: val["b"] = "b1"
p val_c: val["c"]
p val: val


$ ruby hash.rb
{:val_a=>"a1"}
"haitta!!"
{:val_b=>"haitta!!"}
{:val_a=>"a2"}
{:val_b=>"b1"}
"haitta!!"
{:val_c=>"haitta!!"}
{:val=>{"a"=>"a2", "b"=>"b1"}}

すごい。便利。

ちなみにリファレンス見るとちゃんと書いてある。

singleton method Hash.new

読んでいくと

空の新しいハッシュを生成します。ブロックの評価結果がデフォルト値になります。設定したデフォルト値はHash#default_procで参照できます。

ということは別のHash作るときに同じことさせたいときは元のprocを入れれば同じことができるってことか。
やってみる。

val = Hash.new do |hash, key|
  p "haitta!!"
end

p val_a: val["a"] = "a1"
p val_b: val["b"]
p val_a: val["a"] = "a2"
p val_b: val["b"] = "b1"
p val_c: val["c"]
p val: val
p "------------------------------"

p proc: val.default_proc
p "------------------------------"

test = Hash.new &val.default_proc
p test_x: test["x"] = "x1"
p test_y: test["y"]
p test_x: test["x"] = "x2"
p test_y: test["y"] = "y1"
p test_z: test["z"]
p test: test


$ ruby hash.rb
{:val_a=>"a1"}
"haitta!!"
{:val_b=>"haitta!!"}
{:val_a=>"a2"}
{:val_b=>"b1"}
"haitta!!"
{:val_c=>"haitta!!"}
{:val=>{"a"=>"a2", "b"=>"b1"}}
"------------------------------"
{:proc=>#<Proc:0x007fa5f2006c30@hash.rb:1>}
"------------------------------"
{:test_x=>"x1"}
"haitta!!"
{:test_y=>"haitta!!"}
{:test_x=>"x2"}
{:test_y=>"y1"}
"haitta!!"
{:test_z=>"haitta!!"}
{:test=>{"x"=>"x2", "y"=>"y1"}}

こんなことやることあるのかってこともあるけど、これやるなら

val2 = val.dup.clear

このほうがよさそう。

ちなみにArrayも同じようなことできるけど、こっちはsize指定が必要で、要素が確定してるから必ず初期化が動くっぽい。

arr = Array.new(2) do |val|
  p "haitta!!"
end
p arr_0: arr[0] = 1
p arr_1: arr[1]
p arr_2: arr[2]
p arr: arr


$ ruby array.rb
"haitta!!"
"haitta!!"
{:arr_0=>1}
{:arr_1=>"haitta!!"}
{:arr_2=>nil}
{:arr=>[1, "haitta!!"]}

すごい勉強になる。