ASCII-8BITへの変換をどうする的な話
Ruby 1.9 で、なぜ UTF-8 から ASCII-8BIT への変換が Encoding::UndefinedConversionError になるのか分からない。バイナリへの変換ができない?
2012-06-23 06:01:44str.length の値が変化する変換はエラーになる? UTF-8 → BINARY やBINARY -> UTF-8 への encode は、どちらもエラー。force_encoding しか通らない。
2012-06-23 06:06:10UTF-8な文字列が入っているであろうバイナリデータを、UTF-8 な文字列に変換し、変換に失敗したら例外を投げる最も簡単なコードは、
2012-06-23 06:07:49data.force_encoding('UTF-8'); raise "invalid encoding" unless data.valid_encoding? か。簡単でないな。
2012-06-23 06:08:50@frsyuki 「変換」がなにを指しているのか分かりませんが、ASCII-8BITはasciiと互換だけどそれいがいは謎なエンコーディングなので文字コード変換的な処理は書きようがないように思います
2012-06-23 06:14:06しかし encode('BINARY') が失敗しうるので、UTF-8 な String を external_encoding = 'UTF-8' な IO に書き込む際に、Encoding::UndefinedConversionError が発生しうる。
2012-06-23 06:14:22ぃゃ逆だ。external_encoding = 'BINARY' な IO に UTF-8 な文字列を書き込むときに Encoding::UndefinedConversionError が発生しうる
2012-06-23 06:16:02@kosaki55tea 文字の変換ではなくて、エンコーディング指定の変換を意図していました。force_encoding('ASCII-8BIT') を使うべきなのでしょうが、IO#write は String#encode(IO#external_encoding) を呼ぶ
2012-06-23 06:17:58@kosaki55tea ので、external_encoding = 'ASCII-8BIT' な IO に、String#encoding == "UTF-8" な文字列を書き込んでいるときに、「書き込み先は任意のバイナリフォーマットだから、UTF-8で符号化された文字列を
2012-06-23 06:19:30@kosaki55tea 書き込めるだろう」と思っていたら、実際にはASCII非互換の文字列が含まれていた場合に UndefinedConversionError になったので、あれおかしいな?となったわけです。
2012-06-23 06:20:39@frsyuki @kosaki55tea @nurse BINARYならどんなエンコーディングからもエラーなく変換できるといいですね。
2012-06-23 13:56:12@yukihiro_matz @frsyuki @nurse 2.0の100%互換宣言が破られた瞬間であった
2012-06-23 13:59:33@kosaki55tea @yukihiro_matz @frsyuki @nurse エラーが出ないというのは気付かないということなので、今の話のユースケースがよくわかってませんが、エラー無視するAPI新設の方がいいんじゃないかなぁ
2012-06-23 14:31:57@nalsh @yukihiro_matz @frsyuki @nurse わたしも分かっているとは言いがたいのですが set_encoding(nil) で動いたと言っていたので set_encoding(BINARY) って直感的じゃない動作するよねって話じゃないかと
2012-06-23 15:48:55@kosaki55tea @yukihiro_matz @frsyuki 古橋さんの発言をさかのぼってみた感じ、IOにexternal encodingを設定すると自動変換が走るようになるっていう罠にはまったようですね。その辺は仕様と実装両方まずくて改善案が出せないのである
2012-06-23 15:55:15@nalsh @frsyuki @yukihiro_matz set_encoding(BINARY) が意味のある動作をするケースが想像つかないので、set_encoding(nil)と等価にするかいきなり例外上がっちゃった方が親切な気がしなくもないとか思いました
2012-06-23 15:58:55@kosaki55tea @frsyuki @yukihiro_matz IO#set_encodingが犯人かというとそれはちょっと違うんじゃないかな。ならstr.encode("ASCII-8BIT")をforce_encoding("ASCII-8BIT")と読み替えるべき
2012-06-23 16:04:14@nalsh @frsyuki @kosaki55tea たぶん同じ意味だけど、ASCII- 8BITとBINARYの変換器を、どんなエンコーディングからもそのまま受け入れるものにするのがいいんじゃないかな。
2012-06-23 16:37:27@yukihiro_matz @frsyuki @kosaki55tea Unicodeを8ビット固定長エンコーディングに「文字コード変換」できるわけねーだろJKというモヒカン的感覚だとちょっとひっかかりますね
2012-06-23 16:43:36@yukihiro_matz @frsyuki @kosaki55tea そして :xml とか :universal_newline とか指定してた時はどうする問題。なお、str.encode(BINARY)とかする人がとても多いのは知っているので、救うことには反対してません
2012-06-23 16:52:02@yukihiro_matz @nalsh @frsyuki @kosaki55tea 文字を保存する変換器しかなかったところにバイトを保存する変換器を入れると、変換経路を幅優先探索しているところで変な経路が選ばれるはめになる予感がする。対処は可能だろうど変なことだとは思う。
2012-06-23 16:58:10@nalsh え?! 違うんですか? Binaryは(ASCII-8BITも)マジカルエンコーディングだと思ってました。
2012-06-23 16:58:14@nalsh @frsyuki @kosaki55tea BINARYに改行などないという態度で。ASCII-8BITはASCIIを名乗っているぶん、若干悩ましいですね。
2012-06-23 17:01:38