Hash#only, Hash#except
に続いて、Hashを便利にするシリーズです。
今回は、Array#compact
のように、Hashから値が空っぽのキーを取り除く
Hash#compact
を実装してみました。
hash_ext.rb
1 class Hash
2 def compact!(method = :nil?)
3 each do |key, value|
4 value.compact! method if value.respond_to? :compact!
5 delete key if value.send method
6 end
7 end
8
9 def compact(method = :nil?)
10 dup.compact! method
11 end
12 end
非常に簡潔に書けますね。こんな感じの挙動をします。
1 >> {'foo' => [], :bar => nil, :baz => ""}.compact
2 => {"foo"=>[], :baz=>""}
3 >> {'foo' => [], :bar => nil, :baz => ""}.compact :blank?
4 => {}
値がcompact!
を受け取れるオブジェクトの場合は、
再帰的に処理されます。
1 >> {'foo' => {:bar => nil, :baz => ""}}.compact
2 => {"foo"=>{:baz=>""}}
3 >> {'foo' => {:bar => nil, :baz => ""}}.compact :blank?
4 => {}
実際にどんなところで使えるかというと、フォームから送信された
パラメータのうち、空っぽのものを削除してからARのアトリビュートを
更新したい場合なんかに便利かもしれません。
1 class UserController
2 def update
3 @user = User.find(params[:id])
4 @user.update_attributes(params[:user].compact :blank?)
5 end
こんな感じですね。
パスワードとかが空っぽのときは、以前のまま
変更しないというような場合に簡単に対応できます。