StringIO实例改变原始字符串

时间:2018-01-08 19:15:42

标签: ruby utf-8 character-encoding ascii

我观察到使用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的编码,我会期望这样做。

知道这里发生了什么吗?

由于

1 个答案:

答案 0 :(得分:3)

这是故意的 - 如果流是可写的(在IOString的情况下,这将是基础字符串是可写的),那么流上的set_encoding也会在基础字符串上设置编码

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