2

class_eval并且instance_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

怎么来的?任何人都可以阐明这一点吗?

4

1 回答 1

0

让我们来看看这里的 self 是什么:

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 会创建类方法。对于该观察,已经有一个很好的帖子:

于 2016-12-07T17:37:41.973 回答