Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby元类混淆_Ruby_Metaclass - Fatal编程技术网

Ruby元类混淆

Ruby元类混淆,ruby,metaclass,Ruby,Metaclass,我知道ruby中的所有类都是元类类的实例。“常规”对象是这些类的实例(元类的实例) 但我一直想知道,我的意思是类是对象的根,类本身就是类的实例(称为元类,因为它的实例是类)。我在一些博客中看到类的方法new 所以类的行为就像一个类,但它的实例是类。看起来我们有一个圆圈,看起来类本身就是一个实例 我在这里显然漏掉了一点。阶级的起源是什么 下面是一个让我困惑的例子: class Class def new #something end end 但是关键字class意味着类的实例。那

我知道ruby中的所有类都是元类类的实例。“常规”对象是这些类的实例(元类的实例)

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

所以类的行为就像一个类,但它的实例是类。看起来我们有一个圆圈,看起来类本身就是一个实例

我在这里显然漏掉了一点。阶级的起源是什么

下面是一个让我困惑的例子:

class Class
  def new
    #something
  end
end

但是关键字
class
意味着类的实例。那么这是如何工作的呢?

尽管它有点过时,但可能有助于理解这种行为。你可以在Paolo Perrotta的书中找到更深入的主题。

是的,类本身就是一个实例。它是Module的一个子类,也是类的一个实例,Module是Object的一个子类,也是类的一个实例。它确实是非常循环的——但这是核心语言的一部分,而不是库中的东西。Ruby运行时本身没有编写Ruby代码时您或我所具有的限制

不过,我从未听说过“元类”这个词用来谈论课堂。它在Ruby中使用得并不多,但当它被使用时,它通常是官方称为“对象的单例类”的同义词,这是一个比对象模块类更令人困惑的话题

这是怎么工作的

很简单:它没有。无论如何,不是用Ruby

与大多数其他语言一样,有些核心实体被简单地假设为存在。它们从天而降,凭空而出,神奇地出现

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

  • 对象
    没有超类,但不能定义没有超类的类,隐式直接超类始终是
    对象
    。[注意:
    对象可能有实现定义的超类
    ,但最终会有一个没有超类的超类。]
  • 对象
    的一个实例,该类是
    对象
    的一个子类(这意味着间接地
    对象
    对象
    本身的一个实例)
  • 模块
    的子类,它是
  • Class
    Class
这些都不能用Ruby来解释

BasicObject
Object
Module
Class
都需要同时出现,因为它们具有循环依赖关系

仅仅因为这种关系不能用Ruby代码表示,并不意味着Ruby语言规范不能说它必须如此。这取决于实现者找到一种实现方法。毕竟,Ruby实现具有作为程序员所不具备的对对象的访问级别

例如,Ruby实现可以首先创建
BasicObject
,将其
超类
指针和
指针设置为
null

然后,它创建
对象
,将其
超类
指针设置为
基本对象
,将其
指针设置为

接下来,它创建
模块
,将其
超类
指针设置为
对象
,将其
指针设置为

最后,它创建
,将其
超类
指针设置为
模块
,将其
指针设置为

现在,我们可以覆盖
基本对象
对象
模块
,和
指针指向
,我们就完成了

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

然而,一旦它们确实存在,就完全有可能在纯Ruby中实现它们的大部分行为。您只需要这些类的基本版本,由于Ruby的开放类,您可以在以后添加任何缺少的功能

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

因此,完全有可能在纯Ruby中解释
Class#new
的默认行为:

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)
来规避访问限制。]


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

有一个由“twist”链接给出的元循环。它是从根的特征类到
类的内置超类链接。这可以通过以下方式表示:

BasicObject.singleton_class.superclass == Class
x.class == x.eigenclass.superclass(n)
理解
.class
映射的一条线索是将此映射视为从本征类和超类链接派生而来:对于对象
x
x.class
x
本征类的超类链中的第一个类。这可以通过以下方式表示:

BasicObject.singleton_class.superclass == Class
x.class == x.eigenclass.superclass(n)
其中,
eigenclass
singleton\u类的“概念别名”
(抵抗立即值的问题),
y.超类(i)
表示
i
-th超类的
y
n
最小,因此
x.本征类。超类(n)
是一个类。等价地,特征值