2010-11-21 7 views
4

In Ruby 1.9.2, fand ich eine Möglichkeit, zwei Strings, die die gleichen Bytes, die gleiche Codierung und sind gleich, aber sie haben eine andere length und verschiedene Zeichen von [].Warum sind zwei Strings mit gleichen Bytes und Codierung in Ruby 1.9 nicht identisch?

Ist das ein Fehler? Wenn es kein Fehler ist, möchte ich es vollständig verstehen. Welche Art von Informationen werden in Ruby 1.9.2 String-Objekten gespeichert, damit sich diese beiden Strings anders verhalten können?

Unten ist der Code, der dieses Verhalten reproduziert. Die Kommentare, die mit #=> beginnen, zeigen Ihnen, welche Ausgabe ich von diesem Skript erhalte, und die Klammern in Klammern geben Ihnen mein Urteil über diese Ausgabe.

#!/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!) 

Ich benutze Ubuntu und kompilierte Ruby aus der Quelle. Meine Ruby-Version ist:

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

'p string2.bytes.to_a' Ergebnis anzeigen' [194, 162] '?? Das sollte nicht sein! – Zabba

+0

Eigentlich Zabba, das ist das erwartete Ergebnis, weil 194,162 die UTF-8-Codierung des Cent-Zeichens ist (Codepunkt 0xA2). Wenn Sie eine Ganzzahl an concat übergeben, fügt sie Ihrer Zeichenfolge scheinbar ein Zeichen mit diesem Wert hinzu. Sehen Sie diese Tabelle in der Wikipedia aobut UTF-8. Sie verwenden das Cent-Zeichen als Beispiel in der zweiten Zeile: http://en.wikipedia.org/wiki/UTF-8#Description –

Antwort

8

Es ist Rubys Fehler und r29848 fixiert.

+0

Es sieht so aus, als ob du derjenige bist, der es repariert hat. Nett. –

+0

Ich habe Ruby r29852 heruntergeladen und kompiliert, den Testcode ausgeführt, und ich bestätige, dass dieser Fehler behoben wurde! 'string1' und' string2' sind jetzt identisch, soweit ich das beurteilen kann. Danke, Naruse! –

+0

Dieser Link ist defekt, aber der Original-Patch ist unter http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=29848&view=revision und http://svn.ruby-lang.org sichtbar /cgi-bin/viewvc.cgi/trunk/string.c?r1 = 29848 & r2 = 29847 & pathrev = 29848 –

1

Ich denke, das Problem liegt in der Codierung der Zeichenfolge. Sehen Sie sich den Artikel Shades of Gray: Ruby 1.9's String von James Grey zur Unicode-Codierung an.


Zusätzliche merkwürdiges Verhalten:

# 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" 
+0

Ich fand diesen Artikel heute Abend und las das meiste davon, fand aber keine Antwort. Bitte beachten Sie, dass sowohl string1 als auch string2 die gleiche Codierung, UTF-8, haben. Entweder habe ich einen Fehler in Ruby gefunden, oder die Beschreibung von Ruby 1.9 in diesem Artikel ist unvollständig. Der Artikel behauptet "In Ruby 1.9 ist eine Zeichenkette nun eine Sammlung von kodierten Daten. Das bedeutet, dass es sich sowohl um die Rohbytes als auch um die angehängte Kodierungsinformation handelt, wie diese Bytes zu interpretieren sind." Aber diese beiden Strings haben die gleichen Bytes UND die gleiche Codierung, also warum verhalten sie sich anders? Es muss ein anderes wichtiges Attribut von Strings geben. –

+0

Ich lehne mich darauf hin, dass es ein Käfer ist. Die Verwendung von 'concat' mit einer Ganzzahl ist für mich nicht intuitiv. Ich mache ein paar zusätzliche Tests, um zu sehen, was ich ausgraben kann. –

+1

Ich denke, es ist ein Fehler in concat. –

Verwandte Themen