2013-03-17 96 views
0
使用`符号#<=>`

Symbol#<=>混淆`nil`输出时,在Ruby中

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.

我试图返回nil时了解Symbol#<=>作品。这样我打的代码:

>> :x.to_s 
=> "x" 
>> 'x'.to_s 
=> "x" 

从上面的IRB代码我想返回值将是0。但实际是nil。由于doc说在使用<=>运算符to_s之前应用RHOLHO。但在这里,下面的代码不支持这个原则,在我看来。

>> :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不是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); 
} 

但上面的代码我不能understand.But我beleieve它有多么nil正在生产的答案时LHO不是对象类Symbol

任何人都可以帮助我了解nilLHO是不是sym

+0

仔细看看,是不是'rb_str_cmp_m(rb_sym_to_s(sym),rb_sym_to_s(other))' 'nil'是上面的行:'if(!SYMBOL_P(other)){return Qnil; }' – fmendez 2013-03-17 12:33:42

+0

@fmendez是看得很清楚'other'是'RHO'。我正在谈论'LHO'。它首先检查'RHO'如果'sym'或不。如果'RHO'是'sym',那么它只是在'LHO和RHO'上调用'to_s'返回语句。 – 2013-03-17 12:35:31

+0

也许你觉得<=>是一个运营商(因此你在谈论LHO和RHO)时感到困惑。这不是一个真正的操作符,而是一种方法(因此您应该谈论接收者和参数)。 LHO是接收器。我已经扩大了我的答案以澄清。 – AlexChaffee 2013-03-17 12:42:05

回答

3

符号和字符串是不同的类型,因此不具有可比性,就像Fixnum和TrueClass不具有可比性。请参阅Why are symbols not frozen strings?咆哮一下,他们应该如何确定应该是是否相同(即使类Symbol继承自类String的情况)。

在第一个示例中,方法<=>在符号上被调用,并且参数是一个字符串,因此sym_cmp返回nil。

在你的第二个例子中,方法<=>正在一个字符串上被调用,并且该参数是一个符号。所以rb_check_funcall看看它是否可以使用to_str自然地转换成字符串;它不能(“NoMethodError:undefined method to_str for:bar:Symbol”),所以(最终)nil也会在这种情况下返回。 (我们必须深入了解rb_invcmp如何充实“最终”那里:-))

+0

但是您认为文档对于'nil'来看源代码是正确的。我认为文件不清楚。 – 2013-03-17 12:30:19

+0

当我阅读C源代码时,它说“如果另一个不是符号,则返回nil,否则将它们转换为字符串并进行比较”,这似乎是正确的。 – AlexChaffee 2013-03-17 12:32:43

+0

在我的主题中看到我的评论。 – 2013-03-17 12:36:56