Symbol#<=> -> http://www.ruby-doc.org/core-2.0/Symbol.html#metho... 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`?
on 2013-03-17 14:48
on 2013-03-17 15:04
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
on 2013-03-17 15:10
Hans Mackowiak 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 `<main>' > if you "couldn't understand" C code, stop reading it and look at more > easier tutorials
on 2013-03-17 15:19
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
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.