9

我最近发现你可以检测一个类/模块是否包含另一个类/模块。例如,你Array可以Enumerable这样做

Array < Enumerable # true

String然而是不可枚举的

String < Enumerable #nil

这里到底发生了什么?这种语法在 ruby​​ 中是如何工作的?

4

3 回答 3

8

以下是获取类的祖先链的方法:

>> Array.ancestors
=> [Array, Enumerable, Object, Kernel, BasicObject]

如果一个类在祖先链中另一个类的“左边”,则 < 方法返回 true,否则返回 false:

>> Array < Object
=> true
>> Array < Enumerable
=> true

如果一个类不是“左”或祖先链中的另一个类,则 < 方法返回 false。

>> Enumerable < Array
=> false
>> Array < Array
=> false

Enumerable 是一个混入 Array 类,但不混入 String 类的模块。

>> Array.ancestors
=> [Array, Enumerable, Object, Kernel, BasicObject]
>> String.ancestors
=> [String, Comparable, Object, Kernel, BasicObject]

如果将 Enumerable 模型包含在 String 类中,它也会返回 true。

class String
  include Enumerable
end

# Enumerable is now included in String
String < Enumerable #true

由于语法糖,语法有效。在 Ruby 中,一切都是对象,语法糖甚至用于加法等基本操作:

>> 3 + 4
=> 7
>> 3.+(4)
=> 7

< 方法的显式语法如下:

>> Array.<(Object)
=> true
>> Array.send(:<, Object)
=> true
于 2013-07-18T17:58:13.820 回答
4

这里到底发生了什么?这种语法在 ruby​​ 中是如何工作的?

StringArray类继承自从定义类方法的Class类继承的类Module<

如果模块是传递参数的子类,则返回 true。如果两者之间没有关系,则返回 nil。

语法:

Array < Enumerable
String < Enumerable

可以看作:

Array.< Enumerable
String.< Enumerable
于 2013-07-18T17:54:26.583 回答
3

如果这两个模块出现在祖先链中,则通常<=>适用于它们在该链中的位置。如果不是,nil则返回。

于 2013-07-18T17:55:05.477 回答