Ruby 元类混淆 [英] Ruby metaclass confusion

查看:50
本文介绍了Ruby 元类混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 ruby​​ 中的所有类都是元类 Class 的实例.而那个常规"对象是这些类的实例(元类 Class 的实例).

I understand that all classes in ruby are instances of metaclass Class. And that "regular" objects are instances of these classes (the instances of metaclass Class).

但我一直在想,我的意思是类是对象的根,类本身就是类的实例(称为元类,因为它的实例是类).我在一些博客中看到了 Class 类的方法 new 的一些覆盖.

But I keep wondering, I mean classes are root of objects, classes are themselves instances of Class (called metaclass because its instances are classes). I saw in some blogs some overriding of method new, of class Class.

所以 Class 表现为一个类,但它的实例是类.所以看起来我们有一个圆圈,看起来类Class是它自己的一个实例.

So Class behaves as a class, but its instances are classes. So it seems we have a circle, it looks likes class Class is an instance of itself.

我显然在这里遗漏了一点.Class类的由来是什么?

I'm clearly missing a point here. What is the origin of class Class?

这是一个让我困惑的例子:

Here's an example that's confusing me:

class Class
  def new
    #something
  end
end

但是关键字class 暗示类Class 的一个实例.那么这是如何工作的?

But keyword class implies an instance of class Class. So how do this work?

推荐答案

这是如何工作的

简单:没有.无论如何,不​​是在 Ruby 中.

Easy: it doesn't. Not in Ruby, anyway.

就像在大多数其他语言中一样,有一些核心实体只是假设存在.他们从天而降,凭空出现,神奇地出现.

Just like in most other languages, there are some core entities that are simply assumed to exist. They fall from the sky, materialize out of thin air, magically appear.

在 Ruby 中,其中一些神奇的东西是:

In Ruby, some of those magic things are:

  • Object 没有超类,但是你不能定义一个没有超类的类,隐式的直接超类总是Object.[注意:Object 可能有实现定义的超类,但最终会有一个没有超类.]
  • ObjectClass 的一个实例,它是Object 的子类(即间接ObjectObject 本身的一个实例)
  • ClassModule的子类,是Class
  • 的一个实例
  • ClassClass
  • 的一个实例
  • Object doesn't have a superclass, but you cannot define a class with no superclass, the implicit direct superclass is always Object. [Note: there may be implementation-defined superclasses of Object, but eventually, there will be one which doesn't have a superclass.]
  • Object is an instance of Class, which is a subclass of Object (which means that indirectly Object is an instance of Object itself)
  • Class is a subclass of Module, which is an instance of Class
  • Class is an instance of Class

这些东西都不能用 Ruby 来解释.

None of these things can be explained in Ruby.

BasicObjectObjectModuleClass 都需要同时出现,因为它们有循环依赖.

BasicObject, Object, Module and Class all need to spring into existence at the same time because they have circular dependencies.

仅仅因为这种关系不能用 Ruby 代码表达,并不意味着 Ruby 语言规范不能说它必须如此.这取决于实现者想出一种方法来做到这一点.毕竟,Ruby 实现可以访问您作为程序员所没有的对象.

Just because this relationship cannot be expressed in Ruby code, doesn't mean the Ruby Language Specification can't say it has to be so. It's up to the implementor to figure out a way to do this. After all, the Ruby implementation has a level of access to the objects that you as a programmer don't have.

例如,Ruby 实现可以首先创建 BasicObject,将它的 superclass 指针和它的 class 指针设置为 null.

For example, the Ruby implementation could first create BasicObject, setting both its superclass pointer and its class pointer to null.

然后,它创建Object,将它的superclass指针设置为BasicObject,将它的class指针设置为null.

Then, it creates Object, setting its superclass pointer to BasicObject and its class pointer to null.

接下来,它创建Module,将它的superclass指针设置为Object,将它的class指针设置为null.

Next, it creates Module, setting its superclass pointer to Object and its class pointer to null.

最后,它创建了Class,将它的superclass 指针设置为Module 并将它的class 指针设置为null.

Lastly, it creates Class, setting its superclass pointer to Module and its class pointer to null.

现在,我们可以覆盖BasicObjectObjectModuleClassclass 指针指向 Class,我们就完成了.

Now, we can overwrite BasicObject's, Object's, Module's, and Class's class pointer to point to Class, and we're done.

这在系统外部很容易做到,只是从内部看起来很奇怪.

This is easy to do from outside the system, it just looks weird from the inside.

一旦它们确实存在,就完全有可能在普通 Ruby 中实现它们的大部分行为.您只需要这些类的非常简单的版本,感谢 Ruby 的开放类,您可以在以后添加任何缺失的功能.

Once they do exist, however, it is perfectly possible to implement most of their behavior in plain Ruby. You only need very barebones versions of those classes, thanks to Ruby's open classes, you can add any missing functionality at a later time.

在您的示例中,class Class 不是创建名为 Class 的新类,而是重新打开 现有Class,这是运行时环境给我们的.

In your example, the class Class is not creating a new class named Class, it is reopening the existing class Class, which was given to us by the runtime environment.

所以,完全可以用普通的 Ruby 来解释 Class#new 的默认行为:

So, it is perfectly possible to explain the default behavior of Class#new in plain Ruby:

class Class
  def new(*args, &block)
    obj = allocate # another magic thing that cannot be explained in Ruby
    obj.initialize(*args, &block)
    return obj
  end
end

[注意:其实initialize是私有的,所以需要使用obj.send(:initialize, *args, &block)来规避访问限制.]

[Note: actually, initialize is private, so you need to use obj.send(:initialize, *args, &block) to circumvent the access restriction.]

顺便说一句:Class#allocate 是另一种神奇的东西.它在 Ruby 的对象空间中分配了一个新的空对象,这是 Ruby 无法做到的.因此,Class#allocate 也必须由运行时系统提供.

BTW: Class#allocate is another one of those magic things. It allocates a new empty object in Ruby's object space, which is something that cannot be done in Ruby. So, Class#allocate is something that has to be provided by the runtime system as well.

这篇关于Ruby 元类混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆