Confusion with `nil` output from the method Symbol#<=>

Symbol#<=> →

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. nil is
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
->(https://github.com/ruby/ruby/blob/trunk/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?

both the functions return nil because

:x <=> “x” , “x” is not a symbol, so return nil
“x” <=> :x , :x does not respond to to_str, so return nil

if you “couldn’t understand” C code, stop reading it and look at more
easier tutorials

Hans M. wrote in post #1101981:

both the functions return nil because

:x <=> “x” , “x” is not a symbol, so return nil

I understand the above.

“x” <=> :x , :x does not respond to to_str, so return nil

But the above one is confusing. What it returns from the C code:

return rb_str_cmp_m( ? , rb_sym_to_s(other). As string would fail on
rb_sym_to_s(“x”)

“x”.interim
NoMethodError: undefined method interim' for "x":String from (irb):8 from C:/Ruby200/bin/irb:12:in

if you “couldn’t understand” C code, stop reading it and look at more
easier tutorials

WHY DONT YOU GET IT?

this line:
https://github.com/ruby/ruby/blob/trunk/string.c#L2392

symbols does not have a to_str method, so this returns nil or maybe
still the symbol

then because temp is not a String, it calls rb_invcmp
with tries to call symbol <=> string and you should allready know what
that returns