2012年9月2日日曜日

railsでよく見るextract_options!って何やってんの?

class Hash
  def extractable_options?
    instance_of?(Hash)
  end
end

class Array
  #   def options(*args)
  #     args.extract_options!
  #   end
  #
  #   options(1, 2)           # => {}
  #   options(1, 2, :a => :b) # => {:a=>:b}
  def extract_options!
    if last.is_a?(Hash) && last.extractable_options?
      pop
    else
      {}
    end
  end
end
何をやっているか? 配列の最後がHashだったらそれをreturn。
そうでなかったらHashを初期化してreturn
1、Arrayを再オープン
2、is_a?メソッドで配列の最後がHashかどうか確認。
   is_a? レシーバが属するクラスだけでなく、レシーバが属するクラスの親クラスや
   インクルードしているモジュールをklassに指定してもtrueが返ります。
arr = [1, 2, 3]
puts arr.kind_of?(Enumerable)
これはtrueになる。 
3、Hashを再オープン
4、instance_of?で配列の最後がHashかどうか確認。
  レシーバが直接的に属するクラスを指定したときだけtrueになります。
   親クラスを指定するとfalseが返ります。
arr = [1, 2, 3]
puts arr.instance_of?(Enumerable)
これはfalseになる。
5、両方がtrueだったら、popして配列の最後をrerutn、そうでなかったら{}をリターン。 この場合だとlast.is_a?(Hash)がいらない気がする。
extractable_options?の中身が変更されたりするのかな?
last.is_a?(Hash) && last.instance_of?(Hash) でもいいし、
last.instance_of?(Hash)でもいいわけで。
 By default, only instances of Hash itself are extractable.
defaultではハッシュのみが抽出条件だよって書かれているね。
どういう時に変更するんだろう?

0 件のコメント: