Я пытаюсь понять, как работает #lcm
. Он принадлежит классу Integer
, как видно на docs. Я посмотрел на Ruby's github page, но я не знаю, как его перемещать.Как просмотреть метод Ruby #lcm в исходном коде?
Спасибо.
Я пытаюсь понять, как работает #lcm
. Он принадлежит классу Integer
, как видно на docs. Я посмотрел на Ruby's github page, но я не знаю, как его перемещать.Как просмотреть метод Ruby #lcm в исходном коде?
Спасибо.
Лично я предпочитаю читать Rubinius's source code над чтением YARV's. Rubinius гораздо лучше структурированы, гораздо лучше разложенном, и, прежде всего, большинство из них написано на языке Ruby-программисты знают очень хорошо, а именно Ruby:
def lcm(other)
raise TypeError, "Expected Integer but got #{other.class}" unless other.kind_of?(Integer)
if self.zero? or other.zero?
0
else
(self.div(self.gcd(other)) * other).abs
end
end
IronRuby's source code также хорошо структурирован, но уже, к сожалению, не очень поддерживается:
[RubyMethod("lcm")]
public static object/*!*/ Lcm(int self, int other) {
return Lcm(self, other, SignedGcd(self, other));
}
[RubyMethod("lcm")]
public static object/*!*/ Lcm(BigInteger/*!*/ self, BigInteger/*!*/ other) {
return Lcm(self, other, SignedGcd(self, other));
}
[RubyMethod("lcm")]
public static object/*!*/ Lcm(object/*!*/ self, object other) {
throw RubyExceptions.CreateTypeError("not an integer");
}
Мой третий выбор был бы JRuby:
public IRubyObject lcm(ThreadContext context, IRubyObject other) {
checkInteger(context, other);
return f_lcm(context, this, RubyRational.intValue(context, other));
}
что указывает на this:
public static IRubyObject f_lcm(ThreadContext context, IRubyObject x, IRubyObject y) {
if (f_zero_p(context, x) || f_zero_p(context, y)) {
return RubyFixnum.zero(context.runtime);
}
return f_abs(context, f_mul(context, f_div(context, x, f_gcd(context, x, y)), y));
}
Если вы наведете курсор мыши на метод в документах Ruby, вы увидите «нажмите, чтобы переключить источник» справа. Нажмите на нее, и вы увидите ее определение:
VALUE
rb_lcm(VALUE self, VALUE other)
{
other = nurat_int_value(other);
return f_lcm(self, other);
}
Это код C, конечно, а не Ruby. Многие из основных модулей Ruby реализованы на C. Для таких модулей я рекомендую другой источник информации: Ruby Cross-Reference. Там вы можете найти любой идентификатор C, такой как rb_lcm
, и найти его определение. В случае Integer#lcm
это фактически defined in rational.c
(который вы найдете в корневом каталоге GitHub). Оттуда вы можете нажать на f_lcm
, чтобы увидеть its definition:
static VALUE
f_lcm(VALUE x, VALUE y)
{
if (f_zero_p(x) || f_zero_p(y))
return ZERO;
return f_abs(f_mul(f_div(x, f_gcd(x, y)), y));
}
... и так далее.