该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-05-31
最后修改:2010-08-31
按照yugui
大姐的说法,class_eval和instance_eval有如下的区别: class A end class Object def eigenclass class << self;self;end end end A.class_eval do p self def hehe "hehe" end define_method(:xixi) do "xixi" end end A.instance_eval do p self def haha;"haha";p self ;end end A.instance_eval do p self define_method(:hihi) do "hihi" p self.to_s end end A.haha A.new.hihi p A.instance_methods p "*"*120 p A.eigenclass.instance_methods 定义的hihi和xixi都是A是实例方法。
define_method always defines an instance method on the target (Foo in our example). This makes sense because define_method is being call on the implicit self, which evaluates to the receiver (Foo) in our example."[/
A.instance_eval do p self def haha;"haha";p self ;end end A.instance_eval do p self define_method(:hihi) do "hihi" p self.to_s end end A.new.hihi A.haha
事实上,
与 class A
define_method(:hihi) do "hihi"
end end 的效果是一样的,define_method是个私有方法,能调用(隐式)它的只能是类对象而非一般的对象。
现在可以比较直观的理解这二者的不同了
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-05-31
define_method always defines an instance method on the target
|
|
返回顶楼 | |
发表时间:2010-06-01
axgle 写道 define_method always defines an instance method on the target A.instance_eval do p self define_method(:hihi) do "hihi" p self.to_s end end axgle说的是一般情况。上面这个例子就是定义了一个实例方法,如何解释? |
|
返回顶楼 | |
发表时间:2010-06-04
def 是ruby的关键字,他会定义方法到当前的ruby_class(一个隐藏的变量), instance_eval会改变ruby_class,使之成为receiver(A)的meta class(而class_eval则将其变为receiver),所以def定义的方法,就是A的方法(类方法)或者说是A的meta class的实例方法, define_method是ruby中Module的方法,用于定义self的实例方法,instance_eval不会改变self,所以hihi是A的实例方法。 |
|
返回顶楼 | |
发表时间:2010-06-04
hf_cn81 写道
def 是ruby的关键字,他会定义方法到当前的ruby_class(一个隐藏的变量), instance_eval会改变ruby_class,使之成为receiver(A)的meta class(而class_eval则将其变为receiver),所以def定义的方法,就是A的方法(类方法)或者说是A的meta class的实例方法, define_method是ruby中Module的方法,用于定义self的实例方法,instance_eval不会改变self,所以hihi是A的实例方法。 instance_eval 肯定会改变self,无论是用def或者define_method这点可以保证的。 |
|
返回顶楼 | |
发表时间:2010-06-05
最后修改:2010-06-05
instance_eval里的self就是receiver,这和class_eval没有区别,所以 A.instance_eval do puts self end
A.class_eval do puts self end 打印的结果一样,但是instance_eval改变了“ruby_class”到A的meta class,而class_eval则将“ruby_class"改成A。 def定义的方法是做为”ruby_class“的实例方法,而define_method定义的方法是作为self的实例方法。
|
|
返回顶楼 | |
发表时间:2010-06-06
hf_cn81 写道
instance_eval里的self就是receiver,这和class_eval没有区别,所以 A.instance_eval do puts self end
A.class_eval do puts self end 打印的结果一样,但是instance_eval改变了“ruby_class”到A的meta class,而class_eval则将“ruby_class"改成A。 def定义的方法是做为”ruby_class“的实例方法,而define_method定义的方法是作为self的实例方法。
照你的意思,instance_eval中应该有2个不同的self.一个是可以打印出来的的那个,一个就是更改后的ruby_class。对吗? |
|
返回顶楼 | |
发表时间:2010-06-06
我也困惑过。我也来谈谈。
instance_eval,名字上就有instance,就是实例。 什么是实例?a = A.new ,这个a就是实例。 我再自问一句,a实例是什么? 因为在ruby世界里什么都是对象,那个a这个对象其实就是A的单例。 所以你可以这样 def a.method1 puts 'this is singleton method' end a.method1 所以也会有 class A end a = A.new a.instance_eval do self # => a # current class => a's singleton class def method1 puts 'this is a singleton method of instance a' end end a.method1 #=> this is a singleton method of instance a b = A.new b.method1 #=>NoMethodError: undefined method `method1' for #<A:0x10043ff70> 我在想,Ruby是一个语言的大杂烩,不会像Python那样优雅,所以它一定是遵循一种简单的语义。所以我们不能像别其它语言那样,把高度看太高,其实想过来很简单。 coding in fun! ============ class_eval是为Class定义函数。 我知道只要在Class里定义的函数,它的实例就相应得到了这些函数。 class A end a = A.new a.method1 #=> NoMethodError: undefined method `method1' for #<A:0x10043ff70> A.class_eval do self # => A # current class => A def method1 puts 'this is a instance method of class A' end end a.method1 #=> this is a instance method of class A 参考: http://note.jiaeil.com/2010/05/16/digging-ruby-instance_eval-and-class_eval/ |
|
返回顶楼 | |
发表时间:2010-08-31
axgle 写道 define_method always defines an instance method on the target
关键问题是:这个target是指的什么 |
|
返回顶楼 | |
发表时间:2010-08-31
target就是self吧
A.instance_eval{puts self} A.class_eval{puts self} 出来的结果都是A 所以在这两个里面的define_method都是给A定义一个实例方法 instance_eval与class_eval只是给define_method提供了一个self环境 |
|
返回顶楼 | |