Ruby 让人吐血的 Ruby `元编程' 特性.

zw963 · 2012年05月24日 · 最后由 fsword 回复于 2012年07月01日 · 3931 次阅读

仅仅提供两个示例。

请相信我,除非很熟悉 ruby 元编程,而且形成一定的思考惯例!否则一定会让你晕倒,吐血。

class A
end

# 下面的两个示例是相同的.
A.instance_eval { def say_hello; puts "hello"; end }
A.instance_eval { def self.say_hello; puts "hello"; end }

# 下面的两个示例也是相同的
A.instance_eval { define_method(:say_hello) { puts "hello" } }
A.class_eval { define_method(:say_hello) { puts "hello" } }

一切的根源:

default_definee 和 self

@zw963 能解释一下第二个吗

define_method 是定义一个实例方法 Defines an instance method in the receiver. The method parameter can be a Proc or Method object. If a block is specified, it is used as the method body. This block is evaluated using instance_eval, a point that is tricky to demonstrate because define_method is private. (This is why we resort to the send hack in this example.)

而第一个更好理解,block 内部的 self 就是 A 这个类,定义出来的当然是类方法, 只是 A.instance_eval { def say_hello; puts "hello"; end } 默认的 receiver 就是 self 而已

楼主,切莫走火入魔呀

#3 楼 @tumayun

还好啦。哈哈,只是想的更明白了。

你的回复是不对的。准确地说是:default_definee 凑巧和 self 相同而已。

还有

#A.class_eval的current_class应该是A这个class,下面是定义实例方法
A.class_eval { def say_hello; puts "hello"; end }

#A.instance_eval的current_class应该是A的singleton_class,下面是定义类方法
A.instance_eval { def say_hello; puts "hello"; end }

#define_method是Module的方法,定义实例方法
A.instance_eval { define_method(:say_hello) { puts "hello" } }
A.class_eval { define_method(:say_hello) { puts "hello" } }

元编程全部都是围绕 self 开始的,搞清楚 self 是什么就顺畅多了

self, definee, scope 啦

可以从方法定义的角度来理解这件事,def 一个 method(无论是用 def 关键字还是用 define_method ) 时,ruby 会判断此时的 receiver 是否是一个 class,如果是,则 method 放在这个 class 上,否则(即 receiver 是一个普通的 object)method 就要放在这个 object 的 eigen class 上,that all

需要 登录 后方可回复, 如果你还没有账号请 注册新账号