简单地说:在每个符号上调用 to_s 后将符号与 other_symbol 进行比较。根据 symbol 是否小于、等于或大于 other_symbol,返回 -1、0、+1 或 nil。
nil
如果两个值不可比较,则返回。
我试图了解Symbol#<=>
返回时的工作原理nil
。这样做我玩了代码:
>> :x.to_s
=> "x"
>> 'x'.to_s
=> "x"
从上面的IRB
代码我认为返回值将是0
. 但实际是nil
。正如文档所说,在使用<=>
运算符之前to_s
应用了RHO
and LHO
。但是在我看来,下面的代码不支持该原则。
>> :x <=> "x"
#=> nil
所以我试图查看源代码,来回答自己:
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));
}
查看源代码很明显,如果RHO
不是 class 的对象Symbol
,nil
将返回。让我们看看 IRB 中的更多内容:
>> "x" <=> :x
#=> nil
再次nil
。说rb_str_cmp_m(rb_sym_to_s(sym),rb_sym_to_s(other))
现在将执行的源代码。所以现在我去看了STRING.C
. 所以我们基本上是通过rb_str_cmp_m(???,"x")
. 现在我从 github 找到了:(?
意味着不知道什么值)
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);
}
但是上面的代码我无法理解。但我相信它有答案当不是 class 的对象nil
时是如何产生的。LHO
Symbol
任何人都可以在这里帮助我了解什么nil
时候LHO
不来sym
吗?