BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース JRuby1.0における、Unicodeへの対応状況とRubyとの互換性

JRuby1.0における、Unicodeへの対応状況とRubyとの互換性

JRubyにおけるStringの本質は、これまで難しいトピックだった。Rubyはバイト列を使用するのに対し、JavaはStringに対して完全なUnicodeのサポートを行い、内部的にはUTF-16で表現する。Charles O. Nutterが述べている ように、RubyとJRubyでコードを走らせると、微妙な差異として問題はすぐに表面化する。

APIがRubyアプリケーションの期待するところと異なり、個々の文字に対して16ビットの値を頻繁に返してそれを8ビットキャラクタにエンコードできないため、文字列のバイト長が正しくないというエラーがよく報告されます。Rubyのコードと関わる部分で、これはエラーになります。

彼がJRuby 1.0で行った解決策は次のようなものだと述べている。

  • Ruby文字列はbyte[]とし、Ruby文字列のセマンティクスに合わせる。
  • Java文字列がRubyに渡されるところではUTF-8にエンコードされる。これはつまり、文字列を受け取る側はそれをUTF-8のバイト配列として取り扱う必要があるということです。
  • Ruby文字列がRubyを超えてJavaライブラリに渡されるとき、UTF-8であると仮定されます。Java側から戻される文字列もその仮定に従います。

文字エンコーディングの問題を解決しても、それはRubyとの最適な互換性というゴールに達するまでに必要な多くの小さな、つまらないステップの一つでしかない。関連した問題として、Rubyがサポートしている正規表現をJRubyでどうするかという問題がある。簡単な解決策は、長らく使われてきたが、Rubyの正規表現を処理するためにJavaに搭載されている正規表現ライブラリであるjava.util.regexを単純に使用するということである。しかし、微妙な振舞いの違いや他の問題からくるバグレポートが入ってき続け、より良い解決策が必要なのは明らかだった。 java.util.regexのパフォーマンス問題は知られており、Ruby文字列を内部的にバイト配列で表現するという決断によりパフォーマンスはさらに悪くなり得る(java.util.regexはバイト配列に対しては動作しないので、Ruby文字列を扱うためには変換する必要があります)。

そのため、JRubyのコアチームメンバーであるOla Biniは困難に耐え、解決策を列挙して作業に取り掛かることを決断したJRegexを使用するという一時的な解決策をとった後に、彼はREJに取り組んでいる。Ola Biniはこのように述べている。

REJは私が始めたプロジェクトで、MRI 1.8.6正規表現エンジンを直接移植するつもりです。これに関して重要なのは、JRubyが必要としているセマンティクスはMRLに非常に近いということです。我々はUTF-8、SJIS、EUCの正規表現にマッチさせることができ、MRI特有の挙動をまねることもできます(そうした挙動に依存するべきではないとしても)。

2007年5月から、これらを含むさらなる変更が実施される。JRuby 1.0は可能な限りRubyに近づくことはほぼ確実だろう。

(原文は2007年4月10日にリリースされた記事です)

この記事に星をつける

おすすめ度
スタイル

BT