method_missing了解10件事[转]

method_missing了解10件事[转]

本文转自javaeye- hideto的翻译文章:
http://hideto.javaeye.com/blog/108900

===============================================================
我可不是标题党,题目是原作者起的
http://www.thirdbit.net/articles ... out-method_missing/


1,method_missing是一个php?name=Ruby" onclick="tagshow(event)" class="t_tag">Ruby内核方法

2,Rails使用method_missing实现了一些最惊人的magic。当你请求Model的find_by_freaky_column_name方法时,Model会给予
响应,因为ActiveRecord::Base覆盖了内核的method_missing方法。

3,method_missing是方法调用的最后一道防线。当你发送消息到Ruby对象时,Ruby查询与消息同名的方法来调用(有许多方式来
发送消息,最常见的方式是obj.method_name,而你也可以使用obj.send(:method_name)来显示的调用方法)。首先它查询当前
self对象自己的实例方法,然后是该类引入的每个模块,并且是按引入模块的反序。然后它查询该类的父类以及父类引入的模块,
如此这般直到Object类。如果这样仍然找不到该方法,则最后去找的地方就是Object类里引入的Kernel模块,最后将调用的方法
就是method_mising。你可以在方法查询路径里的任何位置覆盖method_missing来告诉Ruby当找不到方法时干什么。

4,我们使用method_missing来实现一些默认行为,更多的是使用它来作为方法工厂或分配器。有时候我们想使用一个类或模块来
做一些同样的工作,我们不知道用户会调用哪个方法,而实现所有的方法看起来又太浪费了。有时候我们添加一个新方法到类中
(factory);有时候我们使用method_missing(dispatcher)。

5,method_missing是Ruby的一个特性,它让我们非常容易创建自己的DSL。DSL为Domain Specific Language。

6,这里是内核的method_missing实现。它是用C写的,可以看到结果是NoMethodError。
代码

 1. irb(main): "thingy".invoke_method_missing_for_demo_purposes("arg", "other arg") 
 2. NoMethodError: undefined method 'invoke_method_missing_for_demo_purposes' for "thingy":String from (irb):227 

7,这里Jamic Buck为我们展示了ActiveRecord::Base怎样覆盖method_missing。

8,method_missing据说比直接调用已经存在的方法慢,确实是这样,因为它是在Ruby查询所有地方后才调用。不过这并不影响使用。

9,method_missing可能对使用你的代码的用户有点不透明,因为动态创建的方法不会有API文档。

10,使用method_missing是Ruby元编程的一个大特性,元编程对其他语言(如Java)开发者而言不是常见的。在method_missing的讨论
中说道:“我不认为元编程在这里是为了节省内存或提高速度。元编程后面的哲学是告诉Ruby你的惯例并让它作一些猜测,以达到节省你的代码的目的。”
正好可以解我的惑,谢谢。
用method_missing用很大的lib,我想builder應該佔有一份名額才是
可以拆builder的源碼學method_missing的運用

Rails中的find部分源碼也是,搭配Regular Expression來判斷使用者輸入的是
find, find_by_xxx, find_by_xxx_or_ooo
或者其他的:P
base.rb