`
googya
  • 浏览: 140295 次
  • 性别: Icon_minigender_1
  • 来自: 汉川
社区版块
存档分类
最新评论

令人迷惑的class_eval和instance_eval

阅读更多

按照yugui 大姐的说法,class_eval和instance_eval有如下的区别:



class&instance_eval              self                            default definee
class_eval                          the receiver                   the receiver
instance_eval                   the receiver                     eigenclass of the receiver




上面就是class_eval与instance_eval的区别了,一般情况下这个没有问题(个人感觉)。但还是会有令迷惑的地方。
下面的例子说明了,在下面情况下,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是实例方法。


 jayfield  
说到:

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."[/

 


jayfield的说法应该是有问题的,但不这样理解,上面的例子怎么又说得通呢?



PS:可能是我表述不清还是怎么的,基本上没有人对此关注。实际上我想说的就是:

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 

 



   同样是用instance_eval,为什么有这么大的不同。

A.new.hihi 
A.haha 

 

事实上,

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

 

 

与 class A

 

  define_method(:hihi) do

     "hihi"

 

end

end

的效果是一样的,define_method是个私有方法,能调用(隐式)它的只能是类对象而非一般的对象。

 

 

 

 


  在一个网站 上看到了这个:

 

 

现在可以比较直观的理解这二者的不同了

 

  • 大小: 29.9 KB
分享到:
评论
16 楼 googya 2011-10-04  
googya 写道
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说的是一般情况。上面这个例子就是定义了一个实例方法,如何解释?



给类对象创建一个实例方法。。。。。那个target就是 A,不管A用instance_eval 或者是 class_eval都是一样的
15 楼 consy 2010-12-29  
<p><span style="font-size: x-small;">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所说:</span></p>
<p><span style="font-size: x-small;">顾名思义<br>instance_eval 就是实例级别的eval<br>class_eval 就是类级别的eval<br><br>A.instance_eval =&gt; open A's singleton instance<br>A.new.instance_eval =&gt; open A.new<br>A.class_eval =&gt; open A<br>class_eval很明显是把接受者当类来看待,所以这个方法只能由类对象来调用,A.class_eval中用def关键字定义方法自然是给A这个类定义方法,应该是</span><span style="font-size: x-small;">hf_cn81所说的ruby_class</span><span style="font-size: x-small;">,这跟类的定义差不多。而A.instance_eval则明显的把A当成一个对象,方法不是存储在对象中的,既然此处不把A当成类,那def定义的方法自然不能是给A定义的(因为A是对象而非类)。所以A.instance_eval中使用def关键字定义的方法就定义到了A这个对象的单例类中了,也就成了A的类方法。</span></p>
<p><span style="font-size: x-small;">我想大概是这样的,不知对也不对大家讨论...</span></p>
<p><span style="font-size: x-small;"><br></span></p>
14 楼 lllyq 2010-09-27  
<div class="quote_title">hf_cn81 写道</div>
<div class="quote_div">
<p>instance_eval里的self就是receiver,这和class_eval没有区别,所以</p>
<p>A.instance_eval do</p>
<p><span style="white-space: pre;"> </span>puts self</p>
<p>end</p>
<p> </p>
<p>A.class_eval do</p>
<p><span style="white-space: pre;"> </span>puts self</p>
<p>end</p>
<p>打印的结果一样,但是instance_eval改变了“ruby_class”到A的meta class,而class_eval则将“ruby_class"改成A。</p>
<p>def定义的方法是做为”ruby_class“的实例方法,而define_method定义的方法是作为self的实例方法。</p>
<p> </p>
</div>
<p>回头看看还是hf_cn81说的比较到位</p>
13 楼 googya 2010-09-27  
从这么多个给我投新手帖的情况来看,我觉得可以反映出2个问题:

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

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

当然对我而言,确实是Ruby新手。但是这个问题却不是那么的simple,也不是那么的stupid。
12 楼 googya 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的实例定义的,这也是我疑惑的地方所在。
   
    不过我想我已经弄清楚了具体的原因!





   





11 楼 ye_jian_hui 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


正解!
10 楼 lllyq 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
9 楼 tjcjc 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环境
8 楼 googya 2010-08-31  
axgle 写道
define_method always defines an instance method on the target

关键问题是:这个target是指的什么
7 楼 xds2000 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/


6 楼 googya 2010-06-06  
<div class="quote_title">hf_cn81 写道</div>
<div class="quote_div">
<p>instance_eval里的self就是receiver,这和class_eval没有区别,所以</p>
<p>A.instance_eval do</p>
<p><span style="white-space: pre;"> </span>puts self</p>
<p>end</p>
<p> </p>
<p>A.class_eval do</p>
<p><span style="white-space: pre;"> </span>puts self</p>
<p>end</p>
<p>打印的结果一样,但是instance_eval改变了“ruby_class”到A的meta class,而class_eval则将“ruby_class"改成A。</p>
<p>def定义的方法是做为”ruby_class“的实例方法,而define_method定义的方法是作为self的实例方法。</p>
<p> </p>
</div>
<p> </p>
<p> </p>
<p>照你的意思,instance_eval中应该有2个不同的self.一个是可以打印出来的的那个,一个就是更改后的ruby_class。对吗?</p>
5 楼 hf_cn81 2010-06-05  
<p>instance_eval里的self就是receiver,这和class_eval没有区别,所以</p>
<p>A.instance_eval do</p>
<p><span style="white-space: pre;"> </span>puts self</p>
<p>end</p>
<p> </p>
<p>A.class_eval do</p>
<p><span style="white-space: pre;"> </span>puts self</p>
<p>end</p>
<p>打印的结果一样,但是instance_eval改变了“ruby_class”到A的meta class,而class_eval则将“ruby_class"改成A。</p>
<p>def定义的方法是做为”ruby_class“的实例方法,而define_method定义的方法是作为self的实例方法。</p>
<p> </p>
4 楼 googya 2010-06-04  
<div class="quote_title">hf_cn81 写道</div><div class="quote_div"><p><span style=""><span style=""><ol class="dp-rb" style="font-size: 1em; line-height: 1.4em; margin-top: 0px; margin-right: 0px; margin-bottom: 1px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; background-color: #ffffff; color: #2b91af; border: 1px solid #d1d7dc;">
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;"><span style="color: black;">A.instance_eval </span><span class="keyword" style="color: #7f0055; font-weight: bold;">do</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">p <span class="keyword" style="color: #7f0055; font-weight: bold;">self</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">    <span class="keyword" style="color: #7f0055; font-weight: bold;">def</span><span style="color: black;"> haha;</span><span class="string" style="color: blue;">"haha"</span><span style="color: black;">;p </span><span class="keyword" style="color: #7f0055; font-weight: bold;">self</span><span style="color: black;"> ;</span><span class="keyword" style="color: #7f0055; font-weight: bold;">end</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;"><span class="keyword" style="color: #7f0055; font-weight: bold;">end</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">  </span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">A.instance_eval <span class="keyword" style="color: #7f0055; font-weight: bold;">do</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">p <span class="keyword" style="color: #7f0055; font-weight: bold;">self</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">    <span class="keyword" style="color: #7f0055; font-weight: bold;">define_method</span><span style="color: black;">(</span><span class="symbol" style="color: #aa7700;">:hihi</span><span style="color: black;">) </span><span class="keyword" style="color: #7f0055; font-weight: bold;">do</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">        <span class="string" style="color: blue;">"hihi"</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">        p <span class="keyword" style="color: #7f0055; font-weight: bold;">self</span><span style="color: black;">.to_s  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">    <span class="keyword" style="color: #7f0055; font-weight: bold;">end</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;"><span class="keyword" style="color: #7f0055; font-weight: bold;">end</span><span style="color: black;">  </span></span></li>
</ol></span></span></p>
<p>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的实例方法。</p></div><br/>instance_eval 肯定会改变self,无论是用def或者define_method这点可以保证的。
3 楼 hf_cn81 2010-06-04  
<p><span style=""><span style=""><ol class="dp-rb" style="font-size: 1em; line-height: 1.4em; margin-top: 0px; margin-right: 0px; margin-bottom: 1px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; background-color: #ffffff; color: #2b91af; border: 1px solid #d1d7dc;">
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;"><span style="color: black;">A.instance_eval </span><span class="keyword" style="color: #7f0055; font-weight: bold;">do</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">p <span class="keyword" style="color: #7f0055; font-weight: bold;">self</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">    <span class="keyword" style="color: #7f0055; font-weight: bold;">def</span><span style="color: black;"> haha;</span><span class="string" style="color: blue;">"haha"</span><span style="color: black;">;p </span><span class="keyword" style="color: #7f0055; font-weight: bold;">self</span><span style="color: black;"> ;</span><span class="keyword" style="color: #7f0055; font-weight: bold;">end</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;"><span class="keyword" style="color: #7f0055; font-weight: bold;">end</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">  </span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">A.instance_eval <span class="keyword" style="color: #7f0055; font-weight: bold;">do</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">p <span class="keyword" style="color: #7f0055; font-weight: bold;">self</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">    <span class="keyword" style="color: #7f0055; font-weight: bold;">define_method</span><span style="color: black;">(</span><span class="symbol" style="color: #aa7700;">:hihi</span><span style="color: black;">) </span><span class="keyword" style="color: #7f0055; font-weight: bold;">do</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">        <span class="string" style="color: blue;">"hihi"</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">        p <span class="keyword" style="color: #7f0055; font-weight: bold;">self</span><span style="color: black;">.to_s  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;">    <span class="keyword" style="color: #7f0055; font-weight: bold;">end</span><span style="color: black;">  </span></span></li>
<li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px;"><span style="color: black;"><span class="keyword" style="color: #7f0055; font-weight: bold;">end</span><span style="color: black;">  </span></span></li>
</ol></span></span></p>
<p>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的实例方法。</p>
2 楼 googya 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说的是一般情况。上面这个例子就是定义了一个实例方法,如何解释?
1 楼 axgle 2010-05-31  
define_method always defines an instance method on the target

相关推荐

    详解Ruby中的instance_eval方法及其与class_eval的对比

    instance_eval方法 这个BasicObject#instance_eval有点类似JS中的bind方法,不同的时,bind是将this传入到对象中,而instance_eval则是将代码块(上下文探针Context Probe)传入到指定的对象中,一个是传对象,一个是...

    Core-Ruby-1:2014 年 10 月开始的 Core Ruby 课程的报告

    核心-Ruby-1 类的存储库。... 不要作恶:class_eval 和 instance_eval。 常量、实例变量 API。 6 自由修补。 改进。 关键字参数。 在 2.1 中风靡一时。 7 线程或:我如何学会停止担心并学会热爱 GI

    scheherazade:Rails 的娱乐装置

    穿得不多(最小的 DSL,没有instance_eval ) 简单示例 # Say we have a model like: class Department belongs_to :company has_many :employees validates_presence_of :company, :name end # Without any ...

    tiny:与框架无关的标记生成器,可用于定义视图助手或用作微型模板化dsl,可与erb和haml一起使用

    它受Erector和Markaby的启发,但具有极简的方法,它选择在其原始上下文中评估内容块,而不是使用instance_eval,因此不需要“走私”实例变量。 它还试图成为一个微小的框架,用于定义要在Rails,Sinatra或任何其他...

    In Javascript Class, how to call the prototype method.(three method)

    1、Using Javascript eval Method。 2、using a veriables save object “this” reference. 3、in innerHTML, we can using String to pass the prototype Method。 e.g. [removed] &lt;!– ...

    mvel 2.0.15

    Lets say we decide to make an instance of this particular class the context object for the expression, and we evaluate it like so: Person personInst = new Person(); personInst.setName("Mr. Foo"); ...

    freemarker总结

    =可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比 较,"x","x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,...

    php.ini-development

    ;;;;;;;;... 1.... 2.... 3.... 4.... 5.... 6.... The syntax of the file is extremely simple.... Section headers (e.g.... at runtime.... There is no name validation.... (e.g.... previously set variable or directive (e.g....

    TCL TK 语言8.5编程指导

    Using the eval command 34 Using the error command 35 Error handling procedure 36 Chapter 4: Handling String Expressions 39 Introduction 40 Appending to a string 41 Formatting a string 42 Matching a ...

    2009 达内Unix学习笔记

    命令和参数之间必需用空格隔开,参数和参数之间也必需用空格隔开。 一行不能超过256个字符;大小写有区分。 二、特殊字符含义 文件名以“.”开头的都是隐藏文件/目录,只需在文件/目录名前加“.”就可隐藏它。...

Global site tag (gtag.js) - Google Analytics