From: "NARUSE, Yui" Date: 2008-01-26T14:12:04+09:00 Subject: [ruby-dev:33402] Re: Binary String 成瀬です。 Hidetoshi NAGAI wrote: > # $KCODE を使うように,必要なメソッドをすべて wrap するというのは > # あまりにも労力が割に合わないので,当然考えてはおられませんよね? そこまでしなくても、-Ke を指定すれば 1.9 のメソッドは対応しますから。 >>>> あとは、ライブラリにブロックを渡すなりしてライブラリ中で処理するか、オブ >>>> ジェクトを受け取ってから設定するかすれば。 >>> え〜っと,それって「ライブラリ側に手を入れる」ってことですよね. >>> 上記の「ライブラリ側に手を入れられないことが前提ならば 」とは >>> 矛盾してしまいませんか.(^_^; >> いえ、[ruby-dev:33269] の例の念頭に置いているので手を入れていません。 > > ライブラリが元々ブロックを受け取ることができる仕様になってなければ > どうしようもないように思えるのですが... > ライブラリ「内」でそうした対応を行わせるためには, > そのライブラリに手を入れるしかないですよね. > 私がまた何か勘違いしているのでしょうか? ブロックを受け取るメソッドの話です。 あとそういえば、Ruby は Open Class なので、外からライブラリのメソッドを 書き換えてしまうという手もあったりはしますね。 > ごめんなさい.nkf は単なる例なのでさして重要ではありません. > 1.8 由来のライブラリ内部で nkf などの別の文字列処理ライブラリなり > 組み込みメソッドなりを呼び出す際, > その 1.8 由来のライブラリは encoding なんてものを知りませんから > 何らかの encoding を仮定 or 想定して文字列を生成し,処理を依頼します. > このとき encoding が指定されてはいないし, > magic comment なんかも入っていませんから, > ASCII-8BIT で文字列が生成される可能性が高いのですよね? nkf の例で何を指そうとしているのかがよくわからないのですが、 エンコーディングを参照しながら何かするライブラリという趣旨ですか? nkf では特殊すぎて例として不適切な気がします。 多くの場合は US-ASCII か ASCII-8BIT になるでしょうね。 > 1.8 版で 1.8 的に動作するもの (encoding を利用するような > (中略) > ライブラリの想定 encoding に合わせて > 戻ってきた文字列に対して force_encoding すれば > 確かになんとか対処できるでしょう. -Kn をつけているケースではそうだと思います。-Ke 等をつけていると少々話は 変わるかもしれません。 > 次に 1.8 版で 1.9 のメソッドを利用するものについてです. > このケースでも nkf のようなものは 1.9 を想定して書かれたわけでは > ないため,magic comment は存在しません. > このとき,1.8 由来のライブラリで生成されて > ASCII-8BIT とされた文字列が nkf のようなものに > 渡される場合を考えます. > メソッドが受け取る引数に依存する点もありますが,結果は > (1) 例外発生 > (2) 適切に処理されて適切な encoding が与えられたものが返る > (3) たまたま適切に処理はされたが encoding は ASCII-8BIT で返る > (ASCII-8BIT はライブラリが想定している encoding ではない) > (4) 例外は生じないが,ASCII-8BIT のまま (不適切に?) 処理され, > 何らかの encoding (ASCII-8BIT?) で返る > というところでしょうか. > 1.8 由来のライブラリは,適切に処理できた場合の encoding を > 知っているでしょうから,その想定に従った処理を行うはずです. > ただし「1.8 由来」ですから,戻値に force_encoding などは > するはずもありません. > 1.8 由来のライブラリで生成された文字列は ASCII-8BIT ですから, > 上記 (2) の場合,処理によっては encoding 不整合でこけます. > こけなければ適切な encoding を持った結果を返せそうです. > 上記 (3) の場合は,処理によっては不適切な結果となるかもしれません. > 戻値の encoding は多分 ASCII-8BIT となるでしょう. > 上記 (4) の場合は,何を返すことになるかわかりません.(^_^; この場合、-K が指定されているかに大きく依存します。-Kn ならば多くの生成 された文字列は ASCI-8BIT になるため、ASCII-8BIT で全体を統一できるかがカ ギになります。この際、バイト単位でなく文字単位で処理を行うコードが混ざっ ていると難しくなります。 一方、-Ke が指定されている場合は全体を EUC-JP で統一できるかがカギとなり ます。この際、バイト単位で処理を行うコードが混ざっているとその周辺でこけ やすくなります。([ruby-list:44536] の例ですね) > 最後に 1.9 版の nkf のようなものを利用するケースです. > 1.8 由来のライブラリで生成された ASCII-8BIT 文字列が渡される場合, > 1.9 版の nkf のようなものはその encoding を信じて処理を行うはずです. > ですが,1.8 由来のライブラリが想定している encoding は > ASCII-8BIT ではありませんから,結果は, > (1) 例外発生 > (2) 例外は生じないが,ASCII-8BIT のまま (不適切に?) 処理され, > 何らかの encoding (ASCII-8BIT?) で返る > というところかもしれません. > 「たまたまうまく」ということが絶対にないとは言い切れませんが. nkf のようなもので何を指しているのかがわかりませんが、 1.8 時代から存在するものであれば、明示的にエンコーディングを指定させてい たはずであり、1.8 なライブラリはエンコーディングを指定して呼び出している はずです。 で、この場合、-Kn をしているケースでは処理の内容によっては救うことは極め て困難に思われます。 "あいうえお".force_encoding("ascii-8bit"). gsub("あいう"){|m|m[0].force_encoding("euc-jp")} というような形に帰着するケースでは難しそうです。 -Ke 等の場合は上述の EUC-JP で統一可能かという話ですね。こちらの場合は、 "あいう" + 0xA4.chr + 0xA8.chr とかがあると難しいかな。 > 見落としがありそうな気もしていますが, > UNDEFINED-8BIT + default_undefind なら > 上記のすべてをかなりの確率で救済できそうな気がします. これで救済できるのは、文字単位での処理か、バイト単位での処理か、どちらか に統一されているケースに限ると思います。そのようなケースでは、エンコー ディング未指定で生成された文字列を -K で指定されたエンコーディングにして しまった方がスマートでしょう。 -- NARUSE, Yui DBDB A476 FDBD 9450 02CD 0EFC BCE3 C388 472E C1EA