実装Read this article in English

言語ごとに異なる複数形 — 「sを付ける」では通用しない理由

ローカライズのコードは、英語の文法にひきずられて誤った前提を持ちがちです。英語はたまたま、あり得る中でも最も単純な部類の複数形システムを持っているからです。名詞は単数か複数のどちらかで、複数形は多くの場合サフィックスを付けて作られます。「個数を数えて、ちょうど1でなければsを付ける」という発想で書かれたコードは、英語では動きますが、世界の大半の言語では静かに壊れます。

数による語形変化は普遍的ではない

日本語の名詞は、数によってまったく語形変化しません。1個を指す場合でも複数を指す場合でも同じ単語が使われ、数を表現する必要がある場合は、名詞自体の変化ではなく文脈や助数詞などの別の手段で表現されます。すべての言語が英語のように「1」と「それ以外」を区別すると仮定したパイプラインは、対象言語にその概念が存在しない場合でも、良くて不自然な、悪ければ冗長な複数マーカーを生み出します。

逆の極にある言語もあります。単数・複数の2区分では足りず、数字そのものや、数字の末尾の桁によって正しい形が変わる、複数のカテゴリを区別しなければならない言語もあります。英語式の2分割ではこうした言語を正しく表現できません。

CLDRの複数形カテゴリ

Unicode Common Locale Data Repository(CLDR)は、多くのローカライズシステムがこの問題で参照する標準的なデータソースで、言語を横断して使われる抽象的な複数形カテゴリ名の固定集合を定義しています。zero、one、two、few、many、otherの6つです。この6つすべてを使う言語はなく、otherはすべての言語が必ず持つフォールバックカテゴリです。英語ではoneとotherの2つだけが使われ、数による語形変化を持たない言語では、どんな数でも常にotherだけが使われます。

ある数字がどのカテゴリに属するか、そしてある言語がそもそもどのカテゴリを持つかは、いずれも言語ごとにCLDRの複数形ルールデータで定義されています。プロジェクトごとにハードコードするようなものではなく、この共有された参照データから引くべきものです。

安易な文字列連結が壊れる理由

よくある2つの近道は、英語を離れた瞬間に破綻します。

  • コード内でサフィックスを付ける方法 — 名詞に条件付きでsを付けて複数形を作るやり方は、対象言語が英語と同じ方法で複数形を表すという前提に立っています。これは翻訳ではなく、出力言語に関係なく実行される、英語の文法規則をロジックに焼き込んだものです。
  • 描画時に数字と名詞を連結する方法 — 数字と空白と名詞をそのまま結合するだけでは、英語の語順を文字列に固定してしまう上、名詞の複数形自体は未解決のままです。名詞の正しい形は、その数字がCLDRのどのカテゴリに属するかで決まるのであって、ゲーム内の他の箇所と同じ単語かどうかでは決まらないからです。

移植可能な表現としてのICU MessageFormat

ICU MessageFormatの複数形構文を使うと、1つの翻訳対象文字列の中に、その言語が必要とするすべてのカテゴリを表現でき、翻訳者はコードに触れることなく、それぞれに正しい言い回しを与えることができます。

{count, plural,
  one {# item}
  other {# items}
}

文字列ファイルへの示唆

ここで言いたいのは、すべてのプロジェクトが初日からICU MessageFormatをフルサポートすべきだということではなく、複数形の扱いをローカライズフォーマットの中で最初から一級市民として設計し、アプリケーションコードに埋め込んだサフィックス規則ではなく、CLDRのカテゴリに基づいて言語ごとに解決すべきだということです。すでに平坦な、英語の形を前提にしたテンプレートで文字列が組まれてしまってから後付けするのは、最初から設計しておくのに比べてはるかに手間がかかります。

関連記事