Hatena::ブログ(Diary)

Cafe Babe RSSフィード

2011-01-13

[] 「Java 6 でIVS比較すると何が起こるか」の記事の誤り

以下の記事に誤りが散見されるが,それが広まるのは望ましくないので,ここで誤りを指摘しておく.

「Java 6 でIVSを比較すると何が起こるか」(yanok.net

まず,Java文字列の同一性判定の話である

これは想像通りですね。単にcharの列を比較しただけの結果になっています。つまり、見た目の区別がつかなくても容赦なく別々の文字列として扱っています。これが何をもたらすかというと、Stringクラス比較しているプログラムに対しては、"与" と "与[0E0100]" と "与[0E0102]" を、見た目の区別がないにもかかわらず、人が入力し分けてやらないと困ることになるということです。

Java言語Unicode文字列が同一性を判定するには,いくつかの方法がある.

  1. java.lang.String#equals()…単なるUnicode文字シーケンスの同一性を判定する
  2. java.text.Collator#equals()…Unicode照合規則に基づいて動的に同一性を判定する
  3. java.text.Collator#getCollationKey()+java.text.CollationKey#compareTo()…Unicode照合規則に基づいて静的にオブジェクトの同一性を判定する
  4. java.text.Collator#getCollationKey()+java.text.CollationKey#toByteArray()+バイナリ比較Unicode照合規則に基づいて静的にバイト列の同一性を判定する
  5. java.text.Normalizer#normalize()+java.lang.String#equals()…Unicode正規化規則に基づいて静的に文字列の同一性を判定する

このように多くの方法があるのは,文字列の同一性判定にいろいろな要求があるからである.たとえば,自然言語の正しい比較は2以降でしか行えないが,プログラミング言語ではUnicode正規化規則や照合規則をあえて適用しないと仕様で規定しているものが多く,その場合には1を用いることになる.また,String#equals()自体はUnicode文字シーケンスを比較しているだけだが,事前にNormalizerを使って正規化しておけば,毎回Collatorを使うよりも高速に処理できることになる(この機能はデータベースの実装に必要なので,私が強く要求して実現したものである).

次にIVS仕様に関する解釈である

UTS #37のIVDの仕様には「variation selectors are default ignorable」と書いてありますが、Javaはignoreしてくれないようです。

この引用部分をさらに長く引用すると,以下の通りである

Furthermore, variation selectors are default ignorable. This implies that registrants are expected to ensure that the glyphic subset associated with an IVS is indeed a subset of the glyphs which are acceptable for the base character alone. Stated another way, the shapes in the glyphic subset of an IVS should be unifiable with the base character of that IVS. One possible way to determine this is to consider the unification rules for Han ideographs; see [Unicode], section 12.1 Han, and [ISO 10646], annex S.

これを読めばすぐ分かるが,ここで述べているのは異体字選択子があったとしても無視して基底文字のグリフで代用してもよいというグリフやレンダリングエンジンにおける話であり,Unicode照合規則やUnicode正規化規則の話ではない(ざっとチェックした限りでは,それらにはまだIVSがらみの変更はないようだが,もし見落としがあれば教えて頂きたい).

つまり,ここでチェックすべき実装の部分はレンダリングエンジンでどのように表示されるかであり,文字列比較に関してはJavaの実装はUnicode標準に沿って実装されていると言える.もし,この部分の仕様に関して実装をチェックするとしたら,Javaレンダリングエンジンでどのように表示されるかであろう.

もちろん,今後各言語仕様や実装において,どのような機能拡張をすべきかという議論はあるだろう.その場合には,私もJavaC#ECMAScript仕様策定や標準化に関わってきたので,何らかの協力ができるかもしれない.

Connection: close