ActiveSupportのHash拡張

認証系のソースを読んでいると『options.reverse_merge! :title => ip_addr』というのが出てきて、こんなの Rubyにあったっけと思って調べたら、やっぱ Rubyにはなくて ActiveSupportのクラス拡張でした。せっかく調べたのでまとめ。

Hash#reverse_merge, Hash#reverse_merge!

Hash#merge(こちらは Rubyに元々あるメソッド)の逆。mergeはキーが重複する場合、値を置き換えるが、reverse_mergeはキーが重複する場合、値を置き換えない。
用途としてこれは便利だとパッと思いつくものはないんだけど、強いてあげれば、初期値のセット(2回目以降の値はセットしない)とか、デフォルト値のセット(値を書き換えない)くらいかな。

options = { :a => 1, :b => 2, :c => 3 }  # => {:a=>1, :b=>2, :c=>3}
options.reverse_merge! :c => 4, :d => 5  # => {:a=>1, :b=>2, :c=>3, :d=>5}

Hash#slice, Hash#slice!

指定されたキーだけの Hashを返す。Hashにないキーを指定してもエラーにはなりません。これは便利かも。

options = { :a => 1, :b => 2, :c => 3 }  # => {:a=>1, :b=>2, :c=>3}
options.slice :b, :c                     # => {:b=>2, :c=>3}

Hash#except, Hash#except!

指定されたキーを除外した Hashを返す。Hashにないキーを指定してもエラーにはなりません。これも便利かも。

options = { :a => 1, :b => 2, :c => 3 }  # => {:a=>1, :b=>2, :c=>3}
options.except :b                        # => {:a=>1, :c=>3}

Hash#diff

2つの Hash間の差異を Hashとして返す。Hashのどっちからやっても同じ結果。

abc = { :a => 1, :b => 2, :c => 3 }
bcd = { :b => 2, :c => 3, :d => 4 }
abc.diff(bcd)                        # => {:a=>1, :d=>4}
bcd.diff(abc)                        # => {:a=>1, :d=>4}

Hash#stringify_keys, Hash#symbolize_keys

stringify_keysは Hashのキーを文字列に変換した Hashとして返す。symbolize_keysは Hashのキーをシンボルに変換して返す。

abc = { :a => 1, "b" => 2, :c => 3 }
abc.stringify_keys                   # => {"a"=>1, "b"=>2, "c"=>3 }
abc.symbolize_keys                   # => {:a=>1, :b=>2, :c=>3 }