Hashによるオプション引数とActiveRecord::Base.extract_options_from_args!
以前、メソッドの引数としてHashを使うといいというエントリーを書きました。
その中で、特にオプション引数に対して有効ということを書きました。
今回は、オプション引数とActiveRecord::Base.extract_options_from_args!を組み合わせるとなかなか便利という話です
携帯の識別番号を設定するメソッド
参考はJpmobileのtestのソース
module ActionController class TestRequest < AbstractRequest attr_accessor :user_agent def guid @env["HTTP_X_DCMGUID"] end def guid=(id) @env["HTTP_X_DCMGUID"] = id end end end def set_ident(end_of_id = '1') @request.user_agent = "DoCoMo/2.0 D902i(c100;TB;W23H16;ser999999999999999;icc0000000000000000000#{end_of_id})" @request.guid = "xxxxxx#{end_of_id}" end
ここに、identを出さないことをシミュレートする、guidだけ出すようにするという風に設定できるようにオプション引数を持たせようとします
def set_ident(end_of_id = '1', options = {}) case when !options[:no_icc] @request.user_agent = "DoCoMo/2.0 D902i(c100;TB;W23H16;ser999999999999999;icc0000000000000000000#{end_of_id})" when !options[:no_guid] @request.guid = "xxxxxx#{end_of_id}" end end #icc, guidともにセットする set_ident #guidはセットしない set_ident('1', :no_guid => true)
しかし、これだと、end_of_idに初期値がセットされている恩恵があまりない。オプション引数を設定する際には必ず第一引数を指定する必要がある。
そこでActiveRecord::Base.extract_options_from_args!を使う。ActiveRecord::Base.extract_options_from_args!の実装は次の通り
def extract_options_from_args!(args) #:nodoc: args.last.is_a?(Hash) ? args.pop : {} end
つまり、渡された引数のうち、最後の引数がHashなら、それはオプション引数であるとあるとみなしている。これを使えばさっきのメソッドは以下のように改善できます。
def set_ident(*args) options = extract_options_from_args!(args) end_of_id = (args.first || '1') case when !options[:no_icc] @request.user_agent = "DoCoMo/2.0 D902i(c100;TB;W23H16;ser999999999999999;icc0000000000000000000#{end_of_id})" when !options[:no_guid] @request.guid = "xxxxxx#{end_of_id}" end end #icc, guidともにセットする set_ident #guidはセットしない set_ident(:no_guid => true)
ActiveRecord::Base.extract_options_from_args!はなかなか使えると思う