Ruby:如何查看Date.leap的定义?

时间:2014-12-22 05:39:38

标签: ruby

我尝试了以下内容:

method = Date.method(:leap?)

puts method

location=method.source_location

puts location

以下是输出:#方法:Date.leap?

1 个答案:

答案 0 :(得分:3)

Date::leap?不是用Ruby编写的,而是用C语言编写的(至少在Ruby的YARV实现上)。

Method#source_location返回Ruby源代码中的位置,但Date::leap? 没有任何Ruby源代码,因此返回nil。< / p>

如果你想找到你想要的东西,你将不得不深入研究YARV的C源。

首先,您在lines 9314-9315 of ext/date/date_core.c上注意到leap?函数实现了date_s_gregorian_leap_p

rb_define_singleton_method(cDate, "leap?", 
                           date_s_gregorian_leap_p, 1);

date_s_gregorian_leap_p的定义在lines 2918-2926 of ext/date/date_core.c上:

static VALUE
date_s_gregorian_leap_p(VALUE klass, VALUE y)
{
    VALUE nth;
    int ry;

    decode_year(y, -1, &nth, &ry);
    return f_boolcast(c_gregorian_leap_p(ry));
}

您会注意到它只是调用了c_gregorian_leap_pinline static int c_gregorian_leap_p(int y) { return (MOD(y, 4) == 0 && y % 100 != 0) || MOD(y, 400) == 0; } 定义了lines 682-686 of ext/date/date_core.c

#define MOD(n,d) ((n)<0 ? NMOD((n),(d)) : (n)%(d))

最后但并非最不重要的是,以下是MOD的定义:

#define NMOD(x,y) ((y)-(-((x)+1)%(y))-1)

NMOD

Date::leap?

但是,我个人认为YARV是所有Ruby实现中最难以理解的。我更喜欢查看JRubyRubinius的源代码。

例如,这里的方法与Rubinius相同。嗯,实际上,与YARV不同,Rubinius没有自己的标准库实现,而是使用RubySL (Ruby Standard Library)项目中的gemified标准库。

正如您在line 730 of lib/rubysl/date/date.rb of the rubysl-date gem上看到的那样,Date::gregorian_leap?被定义为class << self; alias_method :leap?, :gregorian_leap? end 的别名:

def self.gregorian_leap? (y) y % 4 == 0 && y % 100 != 0 || y % 400 == 0 end

上面line 728 of lib/rubysl/date/date.rb of the rubysl-date gem中直接定义了

{{1}}