来自维基教科书的Ruby 编程/概述:
\n\n\n当我说每个 Ruby 对象都有一个类时,我撒了谎。事实上,每个对象都有两个类:\xe2\x80\x9cregular\xe2\x80\x9d 类和单例类。object\xe2\x80\x99s 单例类是一个无名类,其唯一实例是该对象。每个对象都有自己的单例类,与对象一起自动创建。Singleton 类继承自它们的 object\xe2\x80\x99s 常规类,并且最初是空的,但您可以打开它们并向它们添加方法,然后可以在属于它们的单独对象上调用这些方法。
\nThis is Ruby\xe2\x80\x99s secret trick to avoid \xe2\x80\x9cclass methods\xe2\x80\x9d and keep its type system simple and elegant
上面这段话讲述了 Ruby 避免使用类方法的秘密技巧。我不明白作者在这里的意思。Ruby 在哪里阻止我们避免类方法?举个例子,看看下面的例子
\nclass Raj\n def self.hi\n puts \'Hi\'\n end\n def hello\n puts \'hello\'\n end\nend\n\nobject=Raj.new\n\nobject.hello\nRaj.hi\nRun Code Online (Sandbox Code Playgroud)\n正如您在前面的示例中看到的,仍然可以创建类方法。\n是吗?\n我知道 Ruby 中没有真正的类方法;相反,它们是为 Raj 对象创建的方法。\n但是,无论如何,它都允许我创建方法\'hi,\',对吗?\n那么,当它说\n时,它意味着什么? “这是 Ruby 避免“类方法”并保持其类型系统简单而优雅的秘密技巧”?
\n我知道 Ruby 中没有真正的类方法;相反,它们是为 Raj 对象创建的方法。
不过,正是如此。
def self.hi
puts 'Hi'
end
Run Code Online (Sandbox Code Playgroud)
这不是类方法或静态方法。Ruby 中不存在这些。这就是重点。您的类Raj定义了类型的对象Class。我们可以通过#class函数看到它的类型。
> Raj.class
=> Class
Run Code Online (Sandbox Code Playgroud)
我们还可以看到它的祖先。
> Raj.class.ancestors
=> [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
Run Code Online (Sandbox Code Playgroud)
Class继承自Module,因为(在大多数情况下)类可以完成模块可以做的所有事情。Module,反过来,继承自Object,它混合了一些自己的模块(PP:ObjectMixin用于漂亮的打印,并Kernel为您提供像 一样的好帮手puts)并最终继承自根类BasicObject。
但这并不是故事的全部,因为它Raj还有自己的类:它的singleton 类。#singleton_class我们可以通过调用而不是 来查看完整的故事#class。
> Raj.singleton_class.ancestors
=>
[#<Class:Raj>,
#<Class:Object>,
#<Class:BasicObject>,
Class,
Module,
Object,
PP::ObjectMixin,
Kernel,
BasicObject]
Run Code Online (Sandbox Code Playgroud)
现在还有很多事情发生。Raj是 的单例类的实例Raj,它继承自 的单例类Object,而单例类又继承自 的单例类BasicObject,而单例类继承自Class和 我们之前看到的所有内容。
因此,当您在类上定义方法时Raj,您就是在单例类上定义它(作为实例方法)#<Class:Raj>。该类(当前)有一个实例:Raj。
顺便说一句,知道术语“单例类”有点谎言也很有用。正如您所看到的,该类总体上并不是单例。例如,上面Object调用的 的单例类#<Class:Object>实际上有几个实例:Object、Raj、String和大多数 Ruby 类。就我个人而言,出于这个原因,我更喜欢将它们称为特征类,但“单例类”是官方(也是更知名的)术语。
| 归档时间: |
|
| 查看次数: |
203 次 |
| 最近记录: |