2012-06-19 41 views
5

我在Ruby中的Kernel#sprintf方法中遇到了一些混淆。在1.9中運行的Ruby sprintf

Ruby 1.9以不同於Ruby 1.8的方式處理編碼。

下面是我之後的結果,它在Ruby 1.8中的行爲方式:

>> RUBY_VERSION 
=> "1.8.7" 
>> sprintf("%c", 88599) 
=> "\027" 

這是它的行爲在Ruby中1.9:

1.9.3p194 :001 > RUBY_VERSION 
=> "1.9.3" 
1.9.3p194 :002 > sprintf("%c", 88599) 
=> "\u{15A17}" 

如果我用魔評論設置編碼爲二進制(ascii-8bit)我得到一個錯誤:

1.9.3p194 :001 > RUBY_VERSION 
=> "1.9.3" 
1.9.3p194 :002 > # encoding: binary 
1.9.3p194 :003 > sprintf("%c", 88599) 
RangeError: 88599 out of char range 
from (irb):3:in `sprintf' 
from (irb):3 
from /Users/lisinge/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>' 

我也試過這個與Ruby 1.9.2所以th似乎並不是1.9.3所特有的。

也許我做錯了什麼?我不太熟悉Kernel#sprintf方法。

我正在使用名爲ruby-smpp的smpp庫,它可以在github上找到。第#47行的send_concat_mt方法在我嘗試在Ruby 1.9.3中運行時出現了。

如果你們中的任何一位能夠闡明這個問題,我將不勝感激。

+0

它可能開始支持Unicode,因此行爲。我認爲你不應該依賴'sprintf'的這個「特性」。 – nhahtdh

+0

是的,我們可以在我的例子中看到。 而你不厚我應該依靠ruby stdlib中的方法,其中的文檔在兩個版本中都表示相同? 正如我在我的問題中說,似乎我做錯了什麼 – Lisinge

回答

1

sprintf的文檔狀態:

Field | Other Format 
------+-------------------------------------------------------------- 
    c | Argument is the numeric code for a single character or 
     | a single character string itself. 

88599是不適合的對Ruby 1.8的默認行爲一個字符一個有效的數字代碼;我相信這不是編碼。它似乎做的是對你提供的價值做一個模256,然後將其轉換:

% irb 
1.9.3-p194 :003 > 88599 % 256 == 027 
=> true 

至於你做錯了什麼,沒有。發生了什麼事情是允許超出界限的字符代碼是一個已被Ruby 1.9修復的錯誤,它現在正確地引發了一個異常。