论坛首页 入门技术论坛

令人迷惑的class_eval和instance_eval

浏览 8177 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-09-24  
顾名思义
instance_eval 就是实例级别的eval
class_eval 就是类级别的eval

A.instance_eval => open A's singleton instance
A.new.instance_eval => open A.new
A.class_eval => open A
0 请登录后投票
   发表时间:2010-09-25  
lllyq 写道
顾名思义
instance_eval 就是实例级别的eval
class_eval 就是类级别的eval

A.instance_eval => open A's singleton instance
A.new.instance_eval => open A.new
A.class_eval => open A


正解!
0 请登录后投票
   发表时间:2010-09-27  
lllyq 写道
顾名思义
instance_eval 就是实例级别的eval
class_eval 就是类级别的eval

A.instance_eval => open A's singleton instance
A.new.instance_eval => open A.new
A.class_eval => open A


嗯,你说的不错,确实,按照字面上的理解确实如此!
但是关键的问题在于:

A.instance_eval do

    define_method(:hihi) do  
        "hihi"  
        p self.to_s  
   end  
end


这二者的组合产生的效果是什么样的。
A.instance_eval 打开了通往A的eigenclass 的门,在那个门内的方法,按道理来说,仅仅是为A定义的,也就说应该是A单独享有的方法(其实例都不能享有)。但是实际的情况并非如此!hihi这个方法是为A的实例定义的,这也是我疑惑的地方所在。
   
    不过我想我已经弄清楚了具体的原因!





   





0 请登录后投票
   发表时间:2010-09-27  
从这么多个给我投新手帖的情况来看,我觉得可以反映出2个问题:

1、很多人很轻视这个问题。yehuda这个Ruby顶尖高手都曾经在这个问题上犯过错误,     可 见这个问题确实有点迷惑性,因而我觉得有讨论它的价值。从回帖的情况来看,并不是所有人都认清了这个问题的本质。

2、不宽容。那些没有留下只言片语却投了新手帖的人,我不知道他们是什么心态。难道他们都是nb的不行的人物?也许吧,那请你回答这个问题啊,或者可以给点提示、努力的方向都可以啊。

当然对我而言,确实是Ruby新手。但是这个问题却不是那么的simple,也不是那么的stupid。
0 请登录后投票
   发表时间:2010-09-27  
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的实例方法。

 

回头看看还是hf_cn81说的比较到位

0 请登录后投票
   发表时间:2010-12-29   最后修改:2010-12-29

ruby中虽说类也是对象,但类对象跟普通对象是不同的,其中方法(im_tbl)是存储在类中的,并且类还有个super指针来表示继承关系,这是普通对象所不具有的特征。所以可以认为类具有类跟普通对象的双重身份(个人说法...)。instance_eval与class_eval内的self都是方法的接受者,也就是不管是A.instance_eval还是A.class_eval后面所结的代码块的隐含self对象都是A。而define_method是个私有方法。既然是方法,那么在A.instance_eval和A.class_eval中其调用效果都是一样,因为define_method的接受者都是A这个类对象(self),所以在哪调用都是一样的,那么define_method方法所定义的方法就成了了A这个类的实例方法了。而def是个关键字,这个关键字是给类定义方法(方法是存储在类中的)。正如lllyq所说:

顾名思义
instance_eval 就是实例级别的eval
class_eval 就是类级别的eval

A.instance_eval => open A's singleton instance
A.new.instance_eval => open A.new
A.class_eval => open A
class_eval很明显是把接受者当类来看待,所以这个方法只能由类对象来调用,A.class_eval中用def关键字定义方法自然是给A这个类定义方法,应该是
hf_cn81所说的ruby_class,这跟类的定义差不多。而A.instance_eval则明显的把A当成一个对象,方法不是存储在对象中的,既然此处不把A当成类,那def定义的方法自然不能是给A定义的(因为A是对象而非类)。所以A.instance_eval中使用def关键字定义的方法就定义到了A这个对象的单例类中了,也就成了A的类方法。

我想大概是这样的,不知对也不对大家讨论...


0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics