コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

Rubyのhashのメソッドmergeはキーがシンボルと文字列では別物として取り扱われるので気をつける

当たり前といえば当たり前の小ネタ

環境

$ rails -v
Rails 7.0.6
$ ruby -v
ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c5) [arm64-darwin22]

そもそもmergeとは

hashのmergeメソッドは2つのハッシュを1つにまとめ、同じキー名のものをマージする。例えば以下のような動作。

hash = {a: 20, b: 30, c: 40}
merge_hash = {b: 100, c: 500}
hash.merge(merge_hash)
#=> {:a=>20, :b=>100, :c=>500}

キーがシンボルと文字列では別となる

hashのキーを文字列で定義することもできるので、その場合はマージされない。例えば以下のような例。

merge_hash_str = {"a"=> 20 , "b"=>100}
#=> {"a"=>20, "b"=>100}
hash.merge(merge_hash_str)
#=> {:a=>20, :b=>30, :c=>40, "a"=>20, "b"=>100}

自身で定義したhash同士をmergeするときはあまりこのような場面には遭遇しないが、Railsのparamsやgemのconfigをつかっているときなどは留意する必要がある。

もしRailsで対応する場合は symbolize_keys など使って揃えてあげると楽。

hash.merge(merge_hash_str.symbolize_keys)
# => {:a=>20, :b=>100, :c=>40}

関連リンク