【问题标题】:StringIO instance mutating original stringStringIO 实例改变原始字符串
【发布时间】:2018-06-17 19:28:25
【问题描述】:

我观察到使用 Ruby 的 StringIO 类的一些非常奇怪的行为。

在 irb 控制台中键入以下内容:

2.3.0 :002 > original_string = 'test'
 => "test" 
2.3.0 :003 > original_string.encoding
 => #<Encoding:UTF-8> 

编码为 UTF-8。现在构造一个新的 StringIO 实例

2.3.0 :004 > io = StringIO.new(original_string)
 => #<StringIO:0x007fe0ad08e4f0> 
2.3.0 :005 > original_string.encoding
 => #<Encoding:UTF-8> 

original_string 仍然是 UTF-8,现在在派生的 StringIO 实例上设置编码

2.3.0 :006 > io.set_encoding('BINARY')
 => #<StringIO:0x007fe0ad08e4f0> 
2.3.0 :007 > original_string.encoding
 => #<Encoding:ASCII-8BIT> 

原来的字符串编码已经变成了ASCII!这是预期的行为吗?构造 StringIO 对象StringIO.new(original_string.freeze) 可以防止编码更改而不是引发错误,如果original_string 的编码更改是预期的,我会预料到。

知道这里发生了什么吗?

谢谢

【问题讨论】:

  • 您使用的是什么版本的 ruby​​?我相信stringIO 曾经是底层字符串上的一个非常薄的层,但bugs.ruby-lang.org/issues/11827 暗示编码内容现在可能(2.3.x 及更高版本?)在源字符串和 IO 包装器之间是独立的。
  • 我已经在 2.3 和 2.5 上复制了上面的内容

标签: ruby utf-8 character-encoding ascii


【解决方案1】:

这是有意的 - 如果流是可写的(在 IOString 的情况下,如果底层字符串是可写的),那么流上的 set_encoding 也会设置底层字符串的编码。

https://github.com/ruby/ruby/blob/trunk/ext/stringio/stringio.c#L1602

【讨论】:

    猜你喜欢
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多