ruby 如何比较两个日期(或任何其他对象)

How ruby compares two dates(or any other objects)

我只有一行代码,但它给我带来了很多问题。

代码:

Time.at(100).send(:>=, Time.at(200))

主要问题::>= 运算符的实现在哪里?

据我在源代码中看到的,time.c. Or it is? How to know which method from there implement :>=? In the documentation is described only one method for comparing: <=> 中没有 :>= 运算符的实现,但绝对不清楚 :<=> 的调用是如何转换为 :>=.请描述调用跟踪如何在 c 级上调用 :>=

>=方法定义在Comparable模块中。引自文档:

The Comparable mixin is used by classes whose objects may be ordered. The class must define the <=> operator, which compares the receiver against another object, returning a value less than 0, returning 0, or returning a value greater than 0, depending on whether the receiver is less than, equal to, or greater than the other object. If the other object is not comparable then the <=> operator should return nil. Comparable uses <=> to implement the conventional comparison operators (<, <=, ==, >=, and >) and the method between?.

并且 Time Class 包含 Comparable 模块。

在Ruby中,x.y(...)等同于x.send(y, ...),但像x + y这样的东西最终也会被转换成x.send(:+, y)。大多数操作最终都是对某种对象的方法调用。

>= 运算符是一个语法元素,但它是通过调用左侧元素上的 >= 方法来实现的。也就是这段代码:

Time.at(100).send(:>=, Time.at(200))

其中 :>= 是表示 >= 的符号,但您也可以使用 '>=' 代替,即使由于字符串开销它的效率较低。

无论如何,这等同于直接使用运算符:

Time.at(100) >= Time.at(200)

也就是说根本没有 :>= 运算符。它是 >= 运算符 ,由 :>= 符号表示。

出于性能原因,主流 "MRI" version of Ruby 中的许多 Ruby 内部结构都是用 C 语言实现的。这意味着您无法轻易发现该方法的实现位置:

Time.method(:>=).source_location
# => nil

这是因为不涉及 Ruby 代码,而是一个“内部”C 函数。

值得注意的是,您不必直接实现 >= 之类的方法,有一些快捷方式可以自动派生这些方法,特别是 Comparable 会为您执行此操作,如果<=>方法定义:

Comparable uses <=> to implement the conventional comparison operators (<, <=, ==, >=, and >) and the method between?.

换句话说,如果您在 class 中实施 <=>include Comparable,您将免费获得所有这些。时间是否包括可比较的?这很容易发现:

Time.ancestors
# => [Time, Comparable, Object, Kernel, BasicObject]

确实如此。

所以寻找特定的 >= 方法是失败的原因,它是自动生成的。

Ruby C 扩展的定义方式是编写 C 代码,然后通过使用如下绑定桥接方法:

rb_define_method(rb_cTime, "<=>", time_cmp, 1);

其中将 time_cmp() 函数与 rb_cTime class 表示相关联。您也可以在文件中找到该函数的源代码。