class_eval 和 class << 有什么区别类名?

发布于 2024-10-25 09:14:01 字数 409 浏览 3 评论 0 原文

我是红宝石初学者。我发现这两者非常相似(在输出中),但我无法理解以下上下文中的差异。例如,我有一个类

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

I am a Ruby starter. I found both of these are quite similar (in output), but i couldn't understand the difference in the below context. For example, I have a class

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

and can be extended like this

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

and also like this

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

When should I use << and when class_eval?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七颜 2024-11-01 09:14:01

class_evalclass << 没有任何关系。类名

A.class_eval do
   ...
end

相当于

class A
  ...
end

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

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

class << A
  def foo
    ...
  end
end

与注意相同

def A.foo
  ...
end

,如果 A 恰好是一个类(几乎)Ruby 中的所有对象都有单例类,并且您可以使用这两种语法之一为它们定义方法,则它们是唯一的类方法。 class << 的优点obj 主要是如果您一次性定义许多单例方法。

class_eval doesn't really have anything to do with class << className.

A.class_eval do
   ...
end

is equivalent to

class A
  ...
end

with a few differences. class_eval uses a block (or a string, but ignoring that for the moment) which means it closes over the containing lexical scope. In other words you can use local variables from the surrounding scope. The common class block introduces a brand new scope. Likewise you can create the block and pass it to many different class_eval's, and the body of the block will be executed in the context of the class you are calling class_eval on.

class << className opens the singleton class of className, allowing you to define class methods.

class << A
  def foo
    ...
  end
end

Is the same as

def A.foo
  ...
end

Note that they are oly class methods if A happens to be a class (almost) all objects in ruby have singleton classes and you can define methods for them using either of those two syntaxes. The advantage of class << obj is mainly if you're defining many singleton methods in one go.

清醇 2024-11-01 09:14:01

正如已经说过的那样,即使它们在您的示例中似乎做了相同的事情,但 class_eval 实际上并没有多大关系

class <<self

(虽然效果相似,但它的作用并不相同,存在细微的差异)。

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

class A

end


a = A.new
b = A.new

class <<b
  def say_hi
    puts "Hi !"
  end
end


b.say_hi # will print "Hi !"
a.say_hi # will raise an undefined method

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

As already said class_eval has really not much to do with

class <<self

even if they seem to do the same thing in your example (while the effect is similar it does not do the same, there are subtle differences).

Here is another example where the usage of the second form is far more clearer:

class A

end


a = A.new
b = A.new

class <<b
  def say_hi
    puts "Hi !"
  end
end


b.say_hi # will print "Hi !"
a.say_hi # will raise an undefined method

a and b are both objects of the same class A but we added a method to the metaclass of b so the method say_hi is only available to the b object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文