摘自维基图书Ruby Programming/Overview强:

当我说每个Ruby对象都有一个类时,我撒谎了.事实是,每个对象都有两个类:"常规"类和单例类.对象的单例类是一个无名类,其唯一实例是该对象.每个对象都有自己的单例类,与对象一起自动创建.Singleton类继承自其对象的常规类,最初为空,但您可以打开它们并向其中添加方法,然后可以在属于它们的唯一对象上调用这些方法.This is Ruby’s secret trick to avoid “class methods” and keep its type system simple and elegant

上面这段话说的是Ruby避开类方法的秘诀.我不明白作者在这里是什么意思.Ruby在哪里阻止我们避免使用类方法?下面是一个示例,请看下面的示例

class Raj
  def self.hi
    puts 'Hi'
  end
  def hello
    puts 'hello'
  end
end

object=Raj.new

object.hello
Raj.hi

正如您在前面的示例中所看到的,仍然可以创建类方法. 是? 我知道Ruby中没有真正的类方法;相反,它们是为Raj对象创建的方法. 但是,无论如何,它让我可以创建方法"hi",对吗? 那么,当它说‘这是Ruby避免"类方法"并保持其类型系统简单优雅的秘诀时,这是什么意思呢?

推荐答案

我知道Ruby中没有真正的类方法;相反,它们是为Raj对象创建的方法.

不过,就是这样.

def self.hi
  puts 'Hi'
end

这是not个类方法或静态方法.这些在Ruby中并不存在.这就是问题的关键.您的类Raj定义了一个类型为Classobject.我们可以用#class函数来查看它的类型.

> Raj.class
 => Class 

我们还可以看到它的祖先.

> Raj.class.ancestors
 => [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject] 

Class继承自Module,因为(在很大程度上)类可以做模块所能做的一切.Module又继承自Object,Object有自己混合的一些模块(PP:ObjectMixin用于打印美观,Kernel为您提供类似puts的好帮助器),并最终从根类BasicObject继承.

但这并不是故事的全部,因为Raj也有自己的类别:它是singleton class.我们可以通过拨打#singleton_class而不是#class来了解整个故事.

> Raj.singleton_class.ancestors
 => 
[#<Class:Raj>,                                                                  
 #<Class:Object>,                                                               
 #<Class:BasicObject>,                                                          
 Class,                                                                         
 Module,                                                                        
 Object,                                                                        
 PP::ObjectMixin,                                                               
 Kernel,                                                                        
 BasicObject] 

现在,还有更多的事情在发生.RajRaj的Singleton类的一个实例,它继承自Object的Singleton类,而Singleton类又继承自BasicObject的Singleton类,而Singleton类继承自Class和我们之前看到的所有内容.

因此,当您在类Raj上定义方法时,您就是在单例类#<Class:Raj>上定义它(作为实例方法).这个类(目前)有一个实例:Raj.


顺便说一句,知道"单件类"这个术语有点假也是很有用的.正如您所看到的,总的来说,这个类并不是一个单独的类.例如,上面称为#<Class:Object>的单例类Object实际上有几个实例:ObjectRajString和大多数Ruby类.就我个人而言,出于这个原因,我更愿意称它们为eigenclasses,但官方(也是更广为人知的)术语是"单身班级".

Ruby相关问答推荐

Ruby 中的 Float#floor 和 Float#to_i 有什么区别?

Ruby 中的 Hash[key] 返回 nil 但 hash 没有 nil 值

在 Ruby 中,如何编写一个可以与 &:symbol 一起使用的简单方法?

Ruby 匹配第一次出现的字符串以进行 gsub 替换

当没有传入块时,是否有更好的方法来防止屈服?

Ruby 中的 Monad 类似功能

Ruby:通过正则表达式过滤数组?

如何将哈希保存到 CSV

在 Ruby 中,获取第一个块返回 true 的可枚举元素的最快方法是什么?

Ruby 中的发送方法

Ruby 中的抽象方法

如何在 ruby​​ rake 中明确地失败任务?

如何在 Ruby 中创建私有类常量

区分一个Ruby字符串或数组

Ruby 疯狂:类与对象?

Capybara:按值而不是文本 Select 选项

我可以在 OS X v10.6.8 上升级到当前版本的 Ruby (2.2.3) 吗?

在 Ruby 中使用元组?

当我们导入 csv 数据时,如何消除UTF-8 中的无效字节序列

让 sidekiq 立即执行作业(job)