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

Ram*_*Vel 2 ruby class-eval

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

class Say
  def self.hello
    puts "hello"
  end
end
Run Code Online (Sandbox Code Playgroud)

并且可以像这样扩展

class << Say
  def hi
    puts "hi"
  end
end
Run Code Online (Sandbox Code Playgroud)

也喜欢这个

Say.class_eval do
  def self.bye
    puts "bye"
  end
end
Run Code Online (Sandbox Code Playgroud)

我何时应该使用<<何时class_eval

Log*_*ldo 14

class_eval并没有真正的任何关系class << className.

A.class_eval do
   ...
end
Run Code Online (Sandbox Code Playgroud)

相当于

class A
  ...
end
Run Code Online (Sandbox Code Playgroud)

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

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

class << A
  def foo
    ...
  end
end
Run Code Online (Sandbox Code Playgroud)

是相同的

def A.foo
  ...
end
Run Code Online (Sandbox Code Playgroud)

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