2013-03-17 98 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