【问题标题】:Ruby sprintf acting up in 1.9Ruby sprintf 在 1.9 中起作用
【发布时间】:2012-06-30 01:05:19
【问题描述】:

我对 Ruby 中的 Kernel#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 尝试过这个,所以似乎没有特定于 1.9.3。

也许我做错了什么?我对Kernel#sprintf 方法不是很熟悉。

我正在使用一个名为 ruby​​-smpp 的 smpp 库,它可以在 github 上找到。当我尝试在 Ruby 1.9.3 中运行它时,它是第 47 行上的 send_concat_mt 方法。

如果你们中的任何人能对此事有所了解,我将不胜感激。

【问题讨论】:

  • 它可能开始支持 Unicode,因此出现了这种行为。我认为你不应该依赖sprintf 的这个“功能”。
  • 是的,我们可以在我的示例中看到这一点。而且您不认为我应该依赖 ruby​​ stdlib 中的方法,该方法的文档在两个版本中都说相同?正如我在我的问题中所说的,我似乎做错了什么

标签: ruby encoding printf


【解决方案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 默认行为中单个字符的有效数字代码;我相信,这不是编码。它似乎在做的是对您提供的值进行 mod 256,然后对其进行转换:

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

至于你做错了什么,不。实际发生的情况是,允许越界字符代码是 Ruby 1.9 修复的错误,现在可以正确引发异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    相关资源
    最近更新 更多