为什么我使用 #inspect 得到 Encoding::CompatibilityError?

Why do I get a Encoding::CompatibilityError with #inspect?

以下代码可以正常工作:

#encoding: utf-8
class Text
  def initialize(txt)
    @txt = txt
  end
  def inspect
    "<Text: %s>" % @txt
  end
end

p Text.new('Hello World')

但是如果我尝试 p Text.new('Hä, was soll das?') 我会得到一个 Encoding::CompatibilityError:

inspect_with_umlaut.rb:26:in `p': inspected result must be ASCII only or use the default external encoding (Encoding::CompatibilityError)
  from inspect_with_umlaut.rb:26:in `<main>'

这是为什么?

更重要的是:我怎样才能避免它?

错误消息已经解释了原因: 检查结果必须是ASCII或者使用默认的外部编码

在这种情况下,inspect-command 得到一个 UTF-8 字符(不是 ASCII),但默认编码似乎是另一种。 默认编码可以在Encoding.default_external.

中读取

为避免错误,您必须对检查结果进行编码:

#encoding: utf-8
class Text
  def initialize(txt)
    @txt = txt
  end
  def inspect
    #force ASCII and replace invalid/undefined characters
    ("<Text: %s>" % @txt).encode('ASCII', :undef => :replace, :invalid => :replace)
  end
end

p Text.new('Hä, was soll das?') #-> <Text: H?, was soll das?>

代替 encode 中的 ASCII 您还可以使用 Encoding.default_external:

("<Text: %s>" % @txt).encode(Encoding.default_external, :undef => :replace)