前回、前々回、IronRubyの日本語処理について記述してきたが、今回は実際のコードのどの辺が影響しているか記述しようと思う。
前回の以下のコードをデバッガを使って追いかけてみた。
p Dir.glob('/test2/*')
p Dir.glob('/test/*')
単純にステップ実行をしていくと、追いかけるのには苦労するので Dir.glob相当のコードの何ヶ所かにbreakを貼り実行してみた
以下にその時のコードを記載しておく
上記の時のローカル変数は以下のようになる

ここで注目すべきは、MutableStringというclassである。
IronRuby.Builtins.GlobResults は OS から返却されたディレクトリとファイル一覧である。この部分は、実際のpattern "/test/*" にマッチするファイルを収集してくる。この一覧を foreach で繰り返し取得するわけで、それが fileName に代入されている。このfileName は string であり、.NET環境のstring つまり unicode である。実際に、ローカル変数を見ていただくと fileName には "/test/日本語のファイル"という値が入っている。
この後、この fileName を元に MutableString を生成している。このMutableString は IronRuby処理系の独自クラスである。(なお、IronRuby , IronPythonの共通で使う DLR(Dynamic Language Runtime)ではなく、本当にIronRuby処理系独自のクラスのようである。)
このMutableString は 「実際の文字列」とその「エンコーディング」をペアで持つ。(Ruby 1.9の仕様相当だと考えられる)。実際にどのような値が入っているか?たぶん興味が出てくると思う。
もう少しステップ実行した結果を記載すると以下のようになった。
つまり ASCII-8BIT だと思うわけである。この後、このクラスのインスタンスは、"/test/日本語のファイル"という日本語文字列(メモリ内にはunicodeで格納されているが)とエンコーディングはASCII-8BITというペアで記録することになる。
この後、ruby の p メソッドでDir.globの結果が標準出力に渡るわけであるが、この時は unicode ではなく、別のエンコーディングで出力するようになる。つまり p は内部で "/test/日本語のファイル"の値を保持しているMutableString のインスタンスから、別のエンコーディングへ変換しようとする。そう、日本語文字列があるにもかかわらず、それを ASCII-8BITだと思い変換しようとするために、.NETの変換関数 GetByte() で例外が発生するのである。
この結果は、以前にも書いたとおり、以下のような結果となる。
前回 IronRuby 0.9.1 に -Ks を付けると?という記事を書いたが、このデバッグ文章のショットをとっている際に、もしかして -Ks を付けると encodingに ShiftJIS 相当が入るのではないかと思い試した結果となっている。
結論(?)
現状日本語環境でさらに出力をUTF-8などにしたい場合、あまりにも対応が貧弱となっている。このままだと、凄くトリッキーなことをしない限り、利用は難しいと考えられる。




コメントする