If you followed those links, you might be thinking that I screwed them up. I didn't. Looke closely, and you'll notice that the Fixnum#==
docs are actaully repeated twice. Neat.
You might think that's a bug. It's not.
Let's see why:
/* numeric.c */
/*
* call-seq:
* fix == other -> true or false
*
* Return +true+ if +fix+ equals +other+ numerically.
*
* 1 == 2 #=> false
* 1 == 1.0 #=> true
*/
static VALUE
fix_equal(VALUE x, VALUE y)
{
if (x == y) return Qtrue;
if (FIXNUM_P(y)) return Qfalse;
else if (RB_TYPE_P(y, T_BIGNUM)) {
return rb_big_eq(y, x);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
return rb_integer_float_eq(x, y);
}
else {
return num_equal(x, y);
}
}
So there is this c-lang
function fix_equal
that implements double equals, but what about ===
?
/* numeric.c */
rb_define_method(rb_cFixnum, "==", fix_equal, 1);
rb_define_method(rb_cFixnum, "===", fix_equal, 1);
ah-ha! so the code that turns the c function fix_equal
into a ruby method is doubled up, one for ==
and one for ===
. Neat.
Hold on minute! There are other place in the docs where a method has two names and the docs don't have that confusing duplicate entry, like Fixnum#inspect
doc and Fixnum#to_s
doc. Why?
/* numeric.c */
/*
* call-seq:
* fix.to_s(base=10) -> string
*
* Returns a string containing the representation of +fix+ radix +base+
* (between 2 and 36).
*
* 12345.to_s #=> "12345"
* 12345.to_s(2) #=> "11000000111001"
* 12345.to_s(8) #=> "30071"
* 12345.to_s(10) #=> "12345"
* 12345.to_s(16) #=> "3039"
* 12345.to_s(36) #=> "9ix"
*
*/
static VALUE
fix_to_s(int argc, VALUE *argv, VALUE x)
{
int base;
if (argc == 0) base = 10;
else {
VALUE b;
rb_scan_args(argc, argv, "01", &b);
base = NUM2INT(b);
}
return rb_fix2str(x, base);
}
/* numeric.c */
rb_define_method(rb_cFixnum, "to_s", fix_to_s, -1);
rb_define_alias(rb_cFixnum, "inspect", "to_s");
Huh. The only difference that rb_define_alias
was used to define Fixnum#inspect
. Why does ruby do it two different (synonym and alias) and confusing ways? I have no idea.
-- Mark!