为什么 Ruby 1.9 中具有相同字节和编码的两个字符串不相同?

发布于 2024-10-03 18:12:11 字数 1059 浏览 5 评论 0原文

在 Ruby 1.9.2 中,我找到了一种方法来使两个字符串具有相同的字节、相同的编码并且相等,但它们具有不同的 length[] 返回的不同字符

这是一个错误吗?如果这不是一个错误,那么我想完全理解它。 Ruby 1.9.2 String 对象中存储了哪些类型的信息,使得这两个字符串具有不同的行为?

下面是重现此行为的代码。以 #=> 开头的注释显示了我从该脚本中获得的输出,括号内的文字告诉您我对该输出的判断。

#!/usr/bin/ruby1.9
# coding: utf-8
string1 = "\xC2\xA2"       # A well-behaved string with one character (¢)
string2 = "".concat(0xA2)  # A bizarre string very similar to string1.
p    string1.bytes.to_a    #=> [194, 162]  (good)
p    string2.bytes.to_a    #=> [194, 162]  (good)
puts string1.encoding.name #=> UTF-8  (good)
puts string2.encoding.name #=> UTF-8  (good)
puts string1 == string2    #=> true   (good)
puts string1.length        #=> 1      (good)
puts string2.length        #=> 2      (weird!)
p    string1[0]            #=> "¢"    (good)
p    string2[0]            #=> "\xC2" (weird!)

我正在运行 Ubuntu 并从源代码编译了 Ruby。我的 Ruby 版本是:

ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]

In Ruby 1.9.2, I found a way to make two strings that have the same bytes, same encoding, and are equal, but they have a different length and different characters returned by [].

Is this a bug? If it is not a bug, then I'd like to fully understand it. What kind of information is stored inside Ruby 1.9.2 String objects that allows these two strings to behave differently?

Below is the code that reproduces this behavior. The comments that start with #=> show you what output I am getting from this script, and the parenthetical words tell you my judgment of that output.

#!/usr/bin/ruby1.9
# coding: utf-8
string1 = "\xC2\xA2"       # A well-behaved string with one character (¢)
string2 = "".concat(0xA2)  # A bizarre string very similar to string1.
p    string1.bytes.to_a    #=> [194, 162]  (good)
p    string2.bytes.to_a    #=> [194, 162]  (good)
puts string1.encoding.name #=> UTF-8  (good)
puts string2.encoding.name #=> UTF-8  (good)
puts string1 == string2    #=> true   (good)
puts string1.length        #=> 1      (good)
puts string2.length        #=> 2      (weird!)
p    string1[0]            #=> "¢"    (good)
p    string2[0]            #=> "\xC2" (weird!)

I am running Ubuntu and compiled Ruby from source. My Ruby version is:

ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

⊕婉儿 2024-10-10 18:12:11

这是 Ruby 的错误,已修复 r29848

It is Ruby's bug and fixed r29848.

情绪操控生活 2024-10-10 18:12:11

Matz 通过 Twitter 提到了这个问题:

http://twitter.com/matz_translator/status/6597021662187520

< a href="http://twitter.com/matz_translator/status/6597055132733440" rel="nofollow">http://twitter.com/matz_translator/status/6597055132733440

“很难确定这是一个错误,但是,保持原样是不可接受的,我宁愿解决这个问题。”

Matz mentioned this question via Twitter:

http://twitter.com/matz_translator/status/6597021662187520

http://twitter.com/matz_translator/status/6597055132733440

"It's hard to determine as a bug but, it's not acceptable to leave it as is. I'd prefer to fix this issue."

暖心男生 2024-10-10 18:12:11

我认为问题出在字符串的编码上。查看 James Grey 的关于 Unicode 编码的 灰色阴影:Ruby 1.9 的 String 文章。


其他奇怪的行为:

# coding: utf-8

string1 = "\xC2\xA2"       
string2 = "".concat(0xA2)  
string3 = 0xC2.chr + 0xA2.chr

string1.bytes.to_a    # => [194, 162]
string2.bytes.to_a    # => [194, 162]
string3.bytes.to_a    # => [194, 162]

string1.encoding.name # => "UTF-8"
string2.encoding.name # => "UTF-8"
string3.encoding.name # => "ASCII-8BIT"

string1 == string2    # => true
string1 == string3    # => false
string2 == string3    # => true

string1.length        # => 1
string2.length        # => 2
string3.length        # => 2

string1[0]            # => "¢"
string2[0]            # => "\xC2"
string3[0]            # => "\xC2"

string3.unpack('C*') # => [194, 162]
string4 = string3.unpack('C*').pack('C*') # => "\xC2\xA2"
string4.encoding.name # => "ASCII-8BIT"
string4.force_encoding('UTF-8') # => "¢"

string3.force_encoding('UTF-8') # => "¢"
string3.encoding.name # => "UTF-8"

I think the problem is in the string's encoding. Check out James Grey's Shades of Gray: Ruby 1.9's String article on Unicode encoding.


Additional odd behavior:

# coding: utf-8

string1 = "\xC2\xA2"       
string2 = "".concat(0xA2)  
string3 = 0xC2.chr + 0xA2.chr

string1.bytes.to_a    # => [194, 162]
string2.bytes.to_a    # => [194, 162]
string3.bytes.to_a    # => [194, 162]

string1.encoding.name # => "UTF-8"
string2.encoding.name # => "UTF-8"
string3.encoding.name # => "ASCII-8BIT"

string1 == string2    # => true
string1 == string3    # => false
string2 == string3    # => true

string1.length        # => 1
string2.length        # => 2
string3.length        # => 2

string1[0]            # => "¢"
string2[0]            # => "\xC2"
string3[0]            # => "\xC2"

string3.unpack('C*') # => [194, 162]
string4 = string3.unpack('C*').pack('C*') # => "\xC2\xA2"
string4.encoding.name # => "ASCII-8BIT"
string4.force_encoding('UTF-8') # => "¢"

string3.force_encoding('UTF-8') # => "¢"
string3.encoding.name # => "UTF-8"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文