«前の日記(2007-09-25) 最新 次の日記(2007-09-27)» 編集

Matzにっき


2007-09-26 [長年日記]

_ [Ruby] M17N開発会議

この時期になるもまだ詳細が未確定で、 ショーストッパーになりかねないM17N開発を加速するべく 開発会議を開催した。

ほんとは松江でとか思ってたんだけど、 結局秋葉原ダイビルで。

参加者は、私、ささださん、akrさん、なかださん、mputさん、 Martinさん、青学の学生さん。

で、最初の議論は、最近主流っぽいUCS(Universal Character Set)モデルを 採用するか、日本の伝統的文字列処理の延長線上で(ある意味、茨の道)なんとかするか という話。結局、後者で頑張ることに。

で、伝統を尊重して

  • ASCII(7bit)しか含まない文字列/正規表現は特別扱いして相互演算可能に
  • 7bitの範囲内のコードポイントがASCII互換でない文字集合(EBCDICとか)は扱わない
  • (optional)スクリプトはバイト列としてみた時にASCII互換のものだけを許容する。 UTF-16スクリプトとかはナシ
  • (optional)ASCIIの範囲内しか含まない文字列のエンコーディングはASCIIになる
  • デフォルトのエンコーディング(仮にprimary encodingと呼ぶ)があり、それはlocale/コマンドラインオプションのいずれかで指定される
  • エンコーディングを明示的に指定しない入力のエンコーディングはprimary encodingになる
  • エンコーディングを明示的に指定しない出力は文字列のバイト表現を直接出力する
  • encodeメソッドでエンコーディングの変換(とバリデーション)を行う
  • バイト表現を変更せずエンコーディング(タグ)だけ変換するメソッドは別に用意する。 これはエキスパート用なので長い名前にする(仮にforce_encodingと呼ぶ)
  • エンコーディング情報を使うメソッドは

    • 二つのエンコーディングが等しい時→そのエンコーディングに基づき処理
    • 二つの文字列内容がASCIIのみの時→ASCIIエンコーディングで処理
    • それ以外→エラー

    となる

これは議論していないんだけど、JRubyなどでこれをどう実現するかと考えると

  • primary encoding(仮称)はUTF-16で固定。UCSモデル
  • primary external encoding(同じく仮称)を導入し、これをlocale/コマンドラインオプションで指定できるように
  • ASCIIの範囲だからと言ってASCIIにしない

とすればいいんじゃないかな。

追記

成瀬さんからコメントをいただいた。

すでに世界がUTF-8で統一されつつある今、UCSでもCSIでもそう変わらなかったりはするかもしれませんね。

UTF-8はともかくUnicode系では統一されつつありますね。

> (optional)ASCIIの範囲内しか含まない文字列のエンコーディングはASCIIになる
これを optional にするのは危険な気がするのですが、互換性とか大丈夫ですか。

あ、ここでのoptionalというのは「現状の実装ではASCIIにしてる」が、最終的には分からないと言う意味です。1.8との互換性の問題はないでしょう。JRuby的には難しそうなので、なくした方が良いかもしれません。

> 二つのエンコーディングが等しい時→そのエンコーディングに基づき処理
> 二つの文字列内容がASCIIのみの時→ASCIIエンコーディングで処理
> それ以外→エラー

「一方のみASCIIのとき→もう一方エンコーディングで処理」ですよね?

そうですね。

> primary encoding(仮称)
まずこの「primary encoding」が指す対象が何かを決めた方が決めた方がいいように思います。

上でも書きましたように「明示しない時の入力のエンコーディング」です。 それ以上でもそれ以下でもありません。

スクリプトのエンコーディングはmagic comment(pragmaという言葉は使わないことにしました)で 決まりますが、primary encodingとは関係ありません。

なお、[0x82, 0xA0].pack('C*') は BINARY でしょうか。

packの結果はBINARY(ASCII)です。前にもどこかで書きましたが、 実用上の観点からASCIIエンコーディングとbinaryは区別しません(が、8bit目が立っているASCIIエンコーディング文字列は7bitの特別扱いを受けません)。

> primary encoding(仮称)はUTF-16で固定。UCSモデル
ここでいう「primary encoding」は何に関わるのでしょう。String#encodigが常にUTF-16になるという趣旨だと解釈します。

それは違うのでは。primary encodingはあくまでもデフォルトですから、 明示的に指定すればString#encodingは変化するでしょう。 実装としては、おそらくはバイナリのままエンコーディングタグがつくのだと思います。

ので、ここ以降の考察はちょっとズレちゃってるかも。

_ [言語] microBlog >> nobraces: Python indentation for C

CにPythonのインデントによるブロック指定を導入する、という話。

しかし、考えてみれば、Cってのは

  • 制御構造が値を持たない
  • 無名関数がない
  • クロージャがない

と、Pythonでよく見かけるインデントによるブロックの弊害の原因がほとんどない言語 ではないだろうか。

もしかして、これって理想の組み合わせ?

_ [言語] 新言語 Xtalを作る日記 - 2007-09-25(火)

せっかく東京に引っ越したということで、今年の東京ゲームショウに行ってみました。 ...

家に帰って、Xtalのコンパイラに定数伝播、定数畳み込みの機能を実装しつつ寝ました。

ゲームショウに行ったというエントリなのに、 Xtalコンパイラをいじった話が登場しちゃう。 ほんとに言語実装が好きなんだなあ。

共感しちゃう。

それはそれとして、Xtalは最近導入された言語仕様が、独自性が強すぎてちょっと不安なんだけど(first_stepとかblock_catchとか)。 言語デザイナーってのは頑張って独自性・新規性を追求しすぎちゃうと ユーザが離れちゃうし、なにも独自性がないと関心を持ってもらえないし、 難しいバランスが要求される責任だよね。

本日のツッコミ(全7件) [ツッコミを入れる]
_ 成瀬 (2007-10-07 17:42)

すでに世界がUTF-8で統一されつつある今、UCSでもCSIでもそう変わらなかったりはするかもしれませんね。<br><br>> (optional)ASCIIの範囲内しか含まない文字列のエンコーディングはASCIIになる<br>これを optional にするのは危険な気がするのですが、互換性とか大丈夫ですか。<br><br>> 二つのエンコーディングが等しい時→そのエンコーディングに基づき処理<br>> 二つの文字列内容がASCIIのみの時→ASCIIエンコーディングで処理<br>> それ以外→エラー<br><br>「一方のみASCIIのとき→もう一方エンコーディングで処理」ですよね?<br><br>> primary encoding(仮称)<br>まずこの「primary encoding」が指す対象が何かを決めた方が決めた方がいいように思います。<br>「primary encoding」が影響するのは、「エンコーディングを明示的に指定しない入力のエンコーディング」だけでしょうか。<br>「リテラルのエンコーディング」は encoding pragma ですよねぇ。(encoding pragma が指定されていなければ primary encoding?)<br><br>なお、[0x82, 0xA0].pack('C*') は BINARY でしょうか。

_ 成瀬 (2007-10-07 18:03)

> JRubyなどでこれをどう実現するかと考えると・・・<br>以下仮定が多数混ざるのですが、<br>> primary encoding(仮称)はUTF-16で固定。UCSモデル<br>ここでいう「primary encoding」は何に関わるのでしょう。String#encodigが常にUTF-16になるという趣旨だと解釈します。<br>> primary external encoding(同じく仮称)を導入<br>「エンコーディングを明示的に指定しない入力のエンコーディング」及び「リテラルのエンコーディング」のデフォルト値を定めるものと解釈します。また、入力やリテラルは読み込まれたらUTF-16に変換されるものと解釈します。<br>さらに、以上の前提の下に、<br>* String#encoding ASCII(BINARY) か UTF-16 かの2種類<br>* Stringに出力バイト列のエンコーディングを決定する@external_encodingを追加<br>* String#force_encoding(encoding)は、CRubyの動作のままだと矛盾するので、BINARY文字列で用いられた場合はその文字列をencodingとみなしてUTF-16に変換、@external_encoding = encodingする、UTF-16文字列で用いられた場合は@external_encoding = encodingのみとする。<br>* String#encodeの動作はforce_encodingと同様とする。<br><br>これで一つスクリプトを書くと、<br><br>% cat test.dat<br>あいうえお<br>% nkf --guess<br>Shift_JIS<br>% cat test.rb<br>str1 = "\x82\xA0いう" # あいう in Shift_JIS<br>str2 = [0xA4, 0xA2].pack('C*') # あ in EUC-JP<br>str2.force_encoding('EUC-JP')<br>input = ARGF.read<br>puts str1+str2+input<br>% nkf --guess test.rb<br>Shift_JIS<br>% ruby19 --primary-encoding=Shift_JIS test.rb<br>character encodings differ (ArgumentError)<br>% echo jruby --primary-external-encoding=Shift_JIS test.rb<br>あいうああいうえお<br><br>となって、CRubyとJRubyで結果が異なってくるのですが、これは意図した結果でしょうか。<br>互換性を確保するならば<br>% jruby -e'open("euc-jp.dat", "r:euc-jp")'<br>とをエラーにして、<br>% jruby -e'open("euc-jp.dat", "r:utf-16<euc-jp")'<br>常にと書かせればいいのでしょうが、これは違いますよね。<br>おそらく、どのようにforce_encodingやopen時の文字コード変換を整理しても、String#encodingが常にUTF-16という理想を捨てない限り、UCSとCSIを混在させる矛盾がでてくるように感じます。<br>#UCSならば常に二つのStringのエンコーディングは同一なので、CSIとそこが矛盾する

_ なかだ (2007-10-07 18:53)

JRubyはUTF-16 Stringとbyte Stringがあるそうなので、UTF-16以外はbyte Stringでがんばってもらうしかないかもしれませんね。

_ Siena. (2007-10-11 04:30)

テキストとしての US-ASCII とその範囲を超えうる未知のバイト列としての BINARY (or UNKNOWN) は独立して扱えた方が嬉しいです。画像ファイルとか読み込んだのに "US-ASCII" とか言われても不自然に思いますし、US-ASCII の範囲でのみ適用したい処理とかバイナリに対してのみ適用したい処理とかがありえると思います。また、"ASCII-8BIT" と名称変更することには、それらを同一視しているという不便さは残るので反対です。ASCII という名前を含んでいるけど、それから連想されるテキストであることと、あまり相容れない気もします。

_ まつもと (2007-10-11 10:57)

もう少し具体的にどう嬉しいのか、あるいは独立していないとどう困るかについて聞かせてください。<br>「不自然に思います」とか「あまり相容れない気もします」とかだと、結局は「気分の問題」であるようにも読み取れます。<br>「US-ASCII」のバリデーションについては、バイナリが含まれていた場合をちゃんと検出できるようにします。「ASCII-8BIT」の方は素通ししますから、そういう意味では(今の実装ではまだですが)、この両者は区別されることになりますが、そういう意味ではないんですよね。

_ Siena. (2007-10-14 03:36)

US-ASCII と ASCII-8BIT のいずれかしか提供されないものと誤解していました。[ruby-dev:32010] が頭のどこかに残っていて勘違いしたみたいです。すみません。<br><br>それでも、ASCII-8BIT というのが適切な名前ではないかもしれないという疑念は残っています。おっしゃるように個人的な主観ですが、ASCII-8BIT だと、任意のバイト列と言うより、Latin-1 (ISO 8859-1) な文字列と思われる可能性が高そうに思います。場合によっては、実際の文字列は JIS X 0208 だったりするかもしれませんが。で、それらは、やはり任意のバイト列とは違う意図のエンコーディングであるような気がします。少なくともそれらのエンコーディングを指定した人は、それを用いる言語圏で意味が読み取れるテキストを格納するつもりなのではないかな、とか。<br><br>確認ですが、SBCS なエンコーディングも、それぞれ異なるものとして扱われるのですよね? 文字集号とか互換性が無いわけですから、混ぜるな危険、ですし。すると、それらのエンコーディングではない文字列を、BINARY なり UNKNOWN なりで、その他であることを明示できることには意味があるように思います。Latin-1 文字列に、画像ファイルの一部を格納した文字列を連結してしまう、なんてことをしてしまわないように。<br><br>とか考えていたら、未検証なので不明な UNKNOWN(仮) と、既知のエンコーディング以外であると確定された BINARY(仮) の両方があってもいいのかもしれないとか思っちゃいました。今までは、これらの二つは同じ意図のものとして考えてましたが。ややこしくなるので、これは余談てことで。<br># 論理値として true, false の他に nil を使えるみたいに、各種エンコーディング名, BINARY の他に UNKNOWN みたいな?<br><br>任意のバイト列をそれらと区別できると嬉しいかもしれないのは、既知のエンコーディングのテキストか、それ以外の任意のバイナリかによって処理を変えたいという場合ですね。説得力のある例か自信はありませんが、何かのデータ交換用文字列の生成とか、デバグとかログ出力とかの目的で使用する、与えられた任意の String オブジェクトをテキスト出力するメソッドとか。処理はいろいろとバリエーションがありえますが。例えば、テキストが与えられたらエンコーディング変換をして出力したり、改行コードを s/\n/\n\r/g して write したり、fold して整形したり。バイナリが与えられたら (テキストとして出力できるとは期待できないので) hex dump 形式で出力したり、BASE64 エンコードして出力したり、エスケープして出力したり、そういった処理をしたいかもしれません。<br><br>長くなっちゃいましたけど、うまく伝われば良いのですが。<br># ML でやった方が良かったのかしら

_ Siena. (2007-10-16 16:19)

》実際の文字列は JIS X 0208 だったりするかも<br><br>は JIS X 0201 の打ち間違いです。と、補足しなくても汲み取ってもらえると思いますが、念のため。失礼しました。

お名前:
E-mail:
コメント:
[]

«前の日記(2007-09-25) 最新 次の日記(2007-09-27)» 編集

track feed Matzにっき Creative Commons License This work is licensed under a Creative Commons License.