深入到Ruby class_eval和instance_eval

时间:2016-12-07 16:49:21

标签: ruby instance-eval class-eval

class_evalinstance_eval在定义方法等情况下非常容易预测。我也理解了类的实例和类的单例(也就是本征类)之间的区别。

BUT

我无法弄清楚以下唯一的事情: 让我们说,出于某些目的,我们希望将现有的课程设为单身。

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

为什么?任何人都可以了解这一点吗?

1 个答案:

答案 0 :(得分:0)

让我们看看自己在这里:

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创建类方法。这个观察结果已经很好了: