簡體   English   中英

深入了解Ruby class_eval和instance_eval

[英]Deep into Ruby class_eval and instance_eval

在諸如定義方法之類的情況下, class_evalinstance_eval是完全可以預測的。 我也了解類的實例和類的單例(也稱為本征類)之間的區別。

我無法弄清楚像下面這樣的唯一事情:假設出於某種目的,我們希望使現有類成為單例。

class A; end
class B; end

A.class_eval do
  private :new
end

B.instance_eval do
  private :new
end

在兩種情況下都

NameError: undefined method 'new' for class
Did you mean?  new

是的,我的意思就是這種方法。

而且,這兩個變體給出相同的結果,就像兩種情況下類對象的self指向一樣

A.class_eval do
  class << self
    private :new
  end
end

A.new
=> NoMethodError: private method 'new' called for A:Class

B.instance_eval do
  class << self
    private :new
  end
end

B.new
=> NoMethodError: private method 'new' called for B:Class

怎么會? 有人可以闡明這一點嗎?

讓我們來看看這里的自我:

class A
  puts self.inspect

  class << self
    puts self.inspect
  end
end

A.class_eval {
  puts self.inspect

  class << self
    puts self.inspect
  end
}

A.instance_eval{
  puts self.inspect

  class << self
    puts self.inspect
  end
}

我們得到以下輸出:

A
#<Class:A>
A
#<Class:A>
A
#<Class:A>

class_eval方法是為模塊(以及類)定義的,並在模塊(類)的上下文中求值。 instance_eval方法在BasicObject的上下文中求值。 似乎在這些情況下,這兩個(實際上是三個)是同一件事。

但是,我知道一個事實,即如果在eval塊是class_eval創建實例方法和instance_eval的創建類的方法里面創建的方法。 該觀察已經有一篇很好的文章:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM