Hatena::Grouprubyist

Going My Ruby Way このページをアンテナに追加 RSSフィード

Ruby ロゴ (C) Ruby Association LLC

2011年09月07日(水)

incompatible character encodings: UTF-8 and ASCII-8BIT

| 00:52 | incompatible character encodings: UTF-8 and ASCII-8BIT - Going My Ruby Way を含むブックマーク はてなブックマーク - incompatible character encodings: UTF-8 and ASCII-8BIT - Going My Ruby Way incompatible character encodings: UTF-8 and ASCII-8BIT - Going My Ruby Way のブックマークコメント

日本語のメッセージのエンコード箇所で、題名のようなエラーに出くわしました。

以下のように対処しました。

String#bin をメソッドチェーンに挿入します。

(修正前)
    def encode(type)
      case type
             :
        when :mpint    ; this.to_i.bit.div(8).pack("C*").to_packet(4)
        when :string   ; this.to_packet(4)
        when :namelist ; this.join(",").to_packet(4)
             :
      end
    end

(修正後)
    def encode(type)
      case type
            :
        when :mpint    ; this.to_i.bit.div(8).pack("C*").bin.to_packet(4) # 修正
        when :string   ; this.bin.to_packet(4) # 修正
        when :namelist ; this.join(",").bin.to_packet(4) # 修正
            :
      end
    end

String#bin は以下のように定義しています。(String クラスの拡張です)

module GMRW::Extension
     :
  mixin String do
     :
    def bin
      unpack("C*").pack("C*") # UTF-8 などもバイト列に強制変換
    end
  end
end

----------

マニュアルには、以下のようにあります。

>>>

バイト列を表す文字列

文字列ではない単なるバイト列も String オブジェクトで表されます。その時のエンコーディングは ASCII-8BIT です。

<<<

でも

j = "日本語"
j.encoding  # => #<Encoding:UTF-8>
b = j.encode("ASCII-8BIT") # => 例外! Encoding::UndefinedConversionError: ....

。。。変換できない。

(で、bin を作った)と、思ったら String#force_encoding があって、

j = "日本語"
j.encoding  # => #<Encoding:UTF-8>
b = j.force_encoding("ASCII-8BIT")  # OK

逆の変換も、

j = b.force_encoding("UTF-8")
p j           # => "日本語"
p j.encoding  # #<Encoding:UTF-8>

できる。

なんだ、String#bin はこれで代用できるのか。

でも、bin の方が短いし、エンコーディングをどうこうしたいわけではないので、encoding 系のメソッドを使うのは嫌。