我正在使用目前在ruby 1.9.3上运行的遗留项目,并正在调查将其在未来几个月内移至2.3.0
我们有这行代码,这会在不同的ruby版本上返回不同的结果。我想知道这是一个修复过的ruby bug,还是一个新bug,或者是一个记录在案的行为变化。对相关错误票据的引用会有所帮助。
content = "Is your pl\xFFace available?".force_encoding("UTF-8")
content.encode("UTF-8", invalid: :replace) # some other details removed to give smallest code sample
红宝石1.9.3,2.0
的结果"Is your pl\xFFace available?"
ruby 2.1,2.2,2.3的结果
"Is your pl�ace available?"
基本上" \ xFF"被认为是无效的替换,但如果invalid: :replace
省略,它不会引起错误。我猜这可能是因为它是无操作,因为源/目标编码是相同的。
答案 0 :(得分:0)
如果您查看2.0和2.1文档之间的文档差异,您会看到以下文字在2.1中消失:
请注意,从编码enc到相同编码enc的转换是无操作,即返回接收器时没有任何更改,并且即使存在无效字节也不会引发异常。
所以当2.0和更低版本的源代码和目标编码相同且2.1+所做的情况下,2.0和更低版本没有修改字符串时,这种行为似乎是预期的变化。
我不能100%确定您的代码尝试做什么,但如果它尝试从无效的UTF-8字节序列中清除字符串,则可以使用valid_encoding?
和从Ruby 2.1开始scrub
:
irb(main):055:0* content = "Is your pl\xFFace available?"
=> "Is your pl\xFFace available?"
irb(main):056:0> content.valid_encoding?
=> false
irb(main):057:0> new = content.scrub
=> "Is your pl�ace available?"
irb(main):059:0> new.valid_encoding?
=> true
修改强>
如果查看2.0源代码,如果senc(源代码)与denc(目标编码)相同,您将看到str_transcode0
函数exits immediately:
if (senc && senc == denc) {
return NIL_P(arg2) ? -1 : dencidx;
}
在2.1 it scrubs the data中,当编码相同且您明确要求替换无效序列时:
if (senc && senc == denc) {
...
if ((ecflags & ECONV_INVALID_MASK) && explicitly_invalid_replace) {
dest = rb_str_scrub(str, rep);
}
...
}