simply says: Compares symbol with other_symbol after calling to_s on each of the symbols. Returns -1, 0, +1 or nil depending on whether symbol is less than, equal to, or greater than other_symbol.
nilis returned if the two values are incomparable.
I was trying to understand how Symbol#<=> works when returning nil. Doing so I played with the code:
>> :x.to_s
=> "x"
>> 'x'.to_s
=> "x"
From the above IRB code I thought the return value will be 0. But the actual is nil. As doc says that before using <=> operator to_s is applied both the RHO and LHO. But here the below code is not supporting that principle, seems to me.
>> :x <=> "x"
#=> nil
So I tried to see the source code,to answer myself:
static VALUE
sym_cmp(VALUE sym, VALUE other)
{
if (!SYMBOL_P(other)) {
return Qnil;
}
return rb_str_cmp_m(rb_sym_to_s(sym), rb_sym_to_s(other));
}
Looking at the source code it is clear that if RHO is not the object of class Symbol, nil will be returned. Let's see the something
more in IRB:
>> "x" <=> :x
#=> nil
Again nil. The source code saying that rb_str_cmp_m(rb_sym_to_s(sym),rb_sym_to_s(other)) will be executed now. So now I went to the see the source code of STRING.C. So we are basically pasing the rb_str_cmp_m(???,"x"). Now the I found from github:(? means don't know what value)
rb_str_cmp_m(VALUE str1, VALUE str2)
{
int result;
if (!RB_TYPE_P(str2, T_STRING)) {
VALUE tmp = rb_check_funcall(str2, rb_intern("to_str"), 0, 0);
if (RB_TYPE_P(tmp, T_STRING)) {
result = rb_str_cmp(str1, tmp);
}
else {
return rb_invcmp(str1, str2);
}
}
else {
result = rb_str_cmp(str1, str2);
}
return INT2FIX(result);
}
But the above code I couldn't understand.But I beleieve it has the answer how nil is producing when LHO is not the object of class Symbol.
Can anyone help me here to understand how the nil is coming when LHO is not sym?