什么是class_eval和类<< className之间的区别?

我是Ruby的首发。 我发现这些都非常相似(在输出中),但我无法理解下面的上下文中的差异。 例如,我有一个class级

class Say def self.hello puts "hello" end end 

并且可以像这样扩展

 class << Say def hi puts "hi" end end 

也喜欢这个

 Say.class_eval do def self.bye puts "bye" end end 

什么时候应该使用<<class_eval

class_eval实际上与class << className没有任何关系。

 A.class_eval do ... end 

相当于

 class A ... end 

有一些差异。 class_eval使用一个块(或一个字符串,但暂时忽略它),这意味着它会关闭包含的词法范围。 换句话说,您可以使用周围范围内的局部变量。 公共类块引入了一个全新的范围。 同样,您可以创建块并将其传递给许多不同的class_eval,并且块的主体将在您调用class_eval的类的上下文中执行。

class << className打开class << className的单例类,允许您定义类方法。

 class << A def foo ... end end 

是相同的

 def A.foo ... end 

注意它们是oly类方法,如果A碰巧是一个类(几乎),ruby中的所有对象都有单例类,你可以使用这两种语法中的任何一种为它们定义方法。 class << obj的优点主要在于您可以一次定义多个单例方法。

正如已经说过的,class_eval真的没什么关系

 class < 

即使他们似乎在你的例子中做同样的事情(虽然效果相似,但它没有做同样的事情,但存在微妙的差异)。

这是另一个示例,其中第二种forms的使用更加清晰:

 class A end a = A.new b = A.new class < 

a和b都是同一个类A的对象,但我们在b的元类中添加了一个方法,因此方法say_hi仅对b对象可用。