前回(ActiveRecord::Base#find(_by_id)? のお話)の続きのような。
あと、ちゃんとソース読んでないのでなんですが、「find_by_XXX」系メソッドは内部で
method_missingを呼んでるとかいう話なので、当然ただのfindよりオーバヘッドがかかります(特にRuby 1.9系)。なんでもfind_by_idに置き換えるべきではないでしょう。
って書いたんだけど、たまたま当該箇所のソースを張ってらっしゃる方を見かけた。
……method_missing自体のオーバヘッドに加えて、class_eval までしてるし……(w Railsの黒魔術の恐ろしさの一環を垣間見ました。
で、ところどころ、なんかraiseのように使われているsuperが気になった。method_missingの中で呼んでるのはどういうこと?
以下、適当に試す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | def method_missing(meth_id, *args) if match = /^power(\d+)$/.match(meth_id.to_s) $1.to_i ** 2 else super end end #=> nil power2 #=> 4 power10 #=> 100 hoge #=> NameError: undefined local variable or method `hoge' for main:Object # from (irb):12:in `method_missing' # from (irb):20 # from :0 |
メソッドが無いときのデフォルトの挙動、NameError が出る。
アレか。method_missingはもともと、NameErrorをraiseするだけのメソッドとして定義されていて、それをオーバーライドしてるイメージ? なの?
ソースでも、多分そんな感じ。rb_eNameErrorが確かに呼ばれてるみたい。
「マニュアルちゃんと読め。ソース読め。」という結論になりそうな。
Ruby技術者認定試験 公式ガイド (ITpro BOOKs)
著者/訳者:伊藤忠テクノソリューションズ
出版社:日経BP社( 2009-03-25 )
単行本(ソフトカバー) ( 256 ページ )
↑、「いつか受ける」と思って早半年……。
