From: Yukihiro Matsumoto Date: 2008-01-20T02:28:17+09:00 Subject: [ruby-dev:33193] Re: Binary String まつもと ゆきひろです In message "Re: [ruby-dev:33188] Re: Binary String" on Sun, 20 Jan 2008 00:10:55 +0900, Hidetoshi NAGAI writes: |Ruby 1.8 からの Marshal 経由 String のことまで考えると, |UNDEFINED-8BIT (dummy encoding をこれに割り振るのも可?) と |Encoding.default_undefined とを新設した上で, |Ruby 1.9 では Marshal のフォーマットバージョンを |上げてしまうというのが一番すっきりしそうな気がします. 「一番すっきり」という基準がよくわからないのですが、私の主観 ではわからないものは全部「ASCII-8BIT」というのが一番すっきり しています。 が、それでは困るケースも、もしかしたらあるでしょうから、その ような場合には、loadの引数として、(1.8から来たような)エンコー ディング指定がない文字列に付与するエンコーディングの指定を許 すということは考えてもよいと思っています。 |以下,考え違いをしていたらすみません. | |Ruby 1.8 での Marshal では何らかの encoding を想定しているか, |encoding 情報を別に保存しているかの可能性が高いと思われます. |この場合,推測で encoding を与えても推測せずに ASCII-8BIT としても, |多分,どちらも不便だろうと思います. |で,Ruby 1.9 としては,String に encoding は必須であると考えると, |Marshal でも encoding を保存しなければならないはずです. |その意味では,Marshal のフォーマットバージョンは上げるべきと |言っていいのでしょうか? Marshal(1.9)ではエンコーディングは"encoding"というインスタン ス変数として保存されるので、1.8でも問題なく読めます。ので、 この点からはフォーマットバージョンを上げなければならない必然 性はありません。 |問題は Ruby 1.9 で Ruby 1.8 の Marshal 経由 String を |読み込んだ場合ということですよね? | | * この場合,Marshal 経由 String の encoding は UNDEFINED_8BIT にする. | | * Encoding.default_undefined のデフォルト値は ASCII-8BIT とし, | UNDEFINED_8BIT を設定することはできないものとする. | | * UNDEFINED_8BIT の String を処理する際には,その encoding を | Encoding.default_undefined の値であるとして処理する. | UNDEFINED_8BIT の String からの処理結果として生成される文字列の | encoding は,その時点の Encoding.default_undefined の値とし, | UNDEFINED_8BIT が設定されることはないものとする. | | * 参照されただけの String を,UNDEFINED_8BIT から | 現在の default_undefined の値に変更すべきかどうかは要検討. | 参照だけなら変更の必要はないという気もするが, | index だけを得た後で default_undefined の値を変更すると, | index が正しくなくなる可能性がある. | とはいえ,read で書き換えが起こるとした場合は | さらに困ったことになる可能性が高い. | 参照だけならば encoding は変更せず,その後の扱いは | 「自己責任」とするというのが妥当な線かも. | |例えば,Marshal データに特定の encoding を想定している場合は |単純に default_undefined にその encoding を設定すればよいし, |Marshal データの中に encoding 指定を含んでいる場合は, |文字列操作の前にその encoding を default_undefined に |encoding をを設定すればよい. なんだかえらく複雑ですが、default_undefinedをプログラム中から 変更できるならそれは一種の大域変数なので面倒な「状態」を導入 することになります。スレッドセーフじゃなくなるし。それはあま りお勧めではありません。逆に変更できないなら、今度はいろいろ なところからの入力されたエンコーディングが指定されていない文 字列をプログラム全体で一括に扱う必要があり、それはそれで柔軟 性に欠けるように思います。 で、Marshalの件は忘れて、元のTkの話に戻ると、私自身は Identityというエンコーディング(おそらくはdummy)を導入すること に価値がある局面はありえると思っています。名前はともかく。し かし、それはTkからなんらかの理由でエンコーディングがIdentity である文字列をRuby側に導入しなければいけないケースがあり、か つ、そのエンコーディングがASCII-8BITでは明らかにまずく、それ ではないIdentityというエンコーディングでなければならないと示 された場合に限ります。 現時点では、バイナリとASCII-8BITが区別できなくてまずいケース については、(いくつかの例外を除いて)明確に指定されていないよ うに思います。あ、もちろん「バイナリに「ASCII」という名前がつ いているのが気に入らない」という理由もあるのですが、そこはそ れ、歴史的事情なので目をつぶっていただくとして。 残りの点はASCII文字だけから構成されるリテラルのエンコーディン グはASCII-8BITから発生すると思うのですが、この点については近 いうちになにか別のもの(たぶんscript encodingかUS-ASCII)が付与 されると思ってください。どちらかまだ決心できてないけど。 まつもと ゆきひろ /:|)