LoginSignup
42
43

More than 5 years have passed since last update.

Hash の第一引数でのデフォルト値設定は、基本的にすべきではない

Posted at

Ruby の Hash の第一引数のデフォルト値の設定では、破壊的操作をよく行うクラスをセットすると罠にはまります。みんな一度ははまります。

$ pry
[1] pry(main)> h = Hash.new([])
=> {}
[2] pry(main)> h[:a] << 1
=> [1]
[3] pry(main)> h[:b] += [1]
=> [1, 1]
[4] pry(main)> h.keys
=> [:b]
[5] pry(main)> h[:a]
=> [1]

この挙動に何故なるか、理解できる人は手を上げてください!はいあまりいませんね。

なぜこんな挙動になるか、詳しくは以下。

というわけで、デフォルト値の挙動をしっかりと把握してないとはまる人が出てくるので、しっかりと

Hash.new {|h, k| h[k] = [] }

と書くようにしましょう。なお破壊的操作が行われない、例えば Fixnum などは

Hash.new(0)

で問題ないですが、複数人の開発で上記コードが何故問題無いか、を理解してない人が居る可能性がある場合(ほとんどの場合居ます)、へ〜 Hash.new(object) って書けるんだ便利、と理解され、破壊的操作が可能なオブジェクトを突っ込んで問題が起きる(複数回経験アリ)ので、

Hash.new {|h, k| h[k] = 0 }

と冗長でも心がけた方が良いです。

42
43
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
43