2016-06-11 3 views

ответ

2

Лично я предпочитаю читать 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)); 
} 
3

Если вы наведете курсор мыши на метод в документах 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)); 
} 

... и так далее.

Смежные вопросы