Skip to content

Add minimal encoding support to String#inspect #1945

Closed
wants to merge 1 commit into from
View
4 kernel/common/string.rb
@@ -446,10 +446,6 @@ def insert(index, other)
ControlCharacters = [10, 9, 7, 11, 12, 13, 27, 8]
ControlPrintValue = ["\\n", "\\t", "\\a", "\\v", "\\f", "\\r", "\\e", "\\b"]
- def inspect
- "\"#{transform(Rubinius::CType::Printed, true)}\""
- end
-
def ljust(width, padstr=" ")
justify(width, :left, padstr)
end
View
4 kernel/common/string18.rb
@@ -685,4 +685,8 @@ def []=(index, replacement, three=undefined)
end
return replacement
end
+
+ def inspect
+ "\"#{transform(Rubinius::CType::Printed, true)}\""
+ end
end
View
30 kernel/common/string19.rb
@@ -810,4 +810,34 @@ def []=(index, replacement, three=undefined)
end
return replacement
end
+
+ def inspect
+ current_encoding = encoding
+ desired_encoding = Encoding.default_internal || Encoding.default_external
+
+ string = generate_inspected_string(current_encoding, desired_encoding)
+
+ "\"#{string}\""
+ end
+
+ def generate_inspected_string(current_encoding, desired_encoding)
+ if current_encoding == desired_encoding and
+ current_encoding == Encoding::UTF_8
+ table = Rubinius::CType::UTF8Printed
+
+ inspected_string = each_char.collect do |char|
+ if not char.valid_encoding? or char.ord < 256
+ table[char.force_encoding(Encoding::BINARY).ord]
+ else
+ char
+ end
+ end.join
+ inspected_string.gsub!(/(#[$@{])/, '\\\\\1')
+
+ Rubinius::Type.infect(inspected_string, self)
+ inspected_string
+ else
+ transform(Rubinius::CType::Printed, true)
+ end
+ end
end
View
22 kernel/delta/ctype.rb
@@ -1,7 +1,7 @@
# -*- encoding: us-ascii -*-
module Rubinius::CType
- def self.toprint(num)
+ def self.toprint(num, utf8=false)
# The character literals (?x) are Fixnums in 1.8 and Strings in 1.9
# so we use literal values instead so this is 1.8/1.9 compatible.
case num
@@ -14,11 +14,20 @@ def self.toprint(num)
when 13; '\r'
when 27; '\e'
when 34; '\"'
- when 35; Rubinius::Tuple['#$', '\#$', '#@', '\#@', '#{', '\#{', '#', '#']
+ when 35;
+ unless utf8
+ Rubinius::Tuple['#$', '\#$', '#@', '\#@', '#{', '\#{', '#', '#']
+ else
+ '#' # TODO: '#' escaping is handled by String#generate_inspected_string
+ end
when 92; '\\\\'
else
if num < 32 || num > 126
- unprintable_chr(num)
+ unless utf8
+ unprintable_chr(num)
+ else
+ unprintable_utf8_chr(num)
+ end
else
num.chr
end
@@ -32,6 +41,13 @@ def self.toprint(num)
i += 1
end
+ UTF8Printed = Rubinius::Tuple.new 256
+ i = 0
+ while i < 256
+ UTF8Printed[i] = toprint(i, true)
+ i += 1
+ end
+
def toprint
Printed[self]
end
View
6 kernel/delta/ctype18.rb
@@ -6,4 +6,8 @@ def self.unprintable_chr(num)
c = num.to_s 8
str.copy_from c, 0, c.size, 4-c.size
end
-end
+
+ def self.unprintable_utf8_chr(num)
+ unprintable_chr(num)
+ end
+end
View
14 kernel/delta/ctype19.rb
@@ -6,4 +6,16 @@ def self.unprintable_chr(num)
c = num.to_s(16).upcase
str.copy_from c, 0, c.size, 4-c.size
end
-end
+
+ def self.unprintable_utf8_chr(num)
+ if num <= 0x7f
+ str = "\\u0000"
+ str.modify!
+
+ c = num.to_s(16).upcase
+ str.copy_from c, 0, c.size, 6-c.size
+ else
+ unprintable_chr(num)
+ end
+ end
+end
Something went wrong with that request. Please try again.