Next: , Previous: , Up: Programmers   [Contents][Index]


11.3 2つのインターフェースの比較

以下の議論は幾分誇張されたものかもしれません。これまで述べてきたように、わたしたちはUniforumの勧告にしたがう理由があって、GNU gettextを実装しました。しかし、どのようにしてこの決定に至ったかをお見せするべきでしょう。

最初に開発プロセスを概観してみましょう。わたしたちがgettextにより提供されるNLSを使ってアプリケーションを記述するときは、いつものとおり処理のことです。ユーザーの目に触れるので文字列を翻訳する必要があるときだけ、わたしたちは"…"のかわりにgettext("…")を使って翻訳を行います。各ソースファイル(または中核となるヘッダーファイル)で、以下を定義します

#define gettext(String) (String)

この定義により、システムのCライブラリー自体でgettextがサポートされていても、それを無効化できます。このコードをコンパイルすると、NLSコードを使わない場合と同じ結果が得られます。GNU gettextのコードを見ると、gettext("…")のかわりに_("…")を使っているのがわかるでしょう。これにより翻訳可能な文字列のために余分にタイプしなければならない文字数を3文字まで減らせます。

これを出荷するバージョンのプログラムにする場合は、単に以下の定義

#define _(String) (String)

を、以下の定義に置き換えるだけで済みます。

#include <libintl.h>
#define _(String) gettext (String)

そして、翻訳可能な文字列を含むすべてのソースファイルにたいしてxgettextプログラムを実行します。わたしたちは翻訳が利用できないものにたいしても、利用可能になったら使えるように、プログラムを実行します。

同様のことはgettext_noop呼び出しでも行うことができます(Special casesを参照してください)。gettext_noopは通常、no-op(訳注: no-operation = 何もしない) マクロとして定義します。プロジェクトでは以下のようなコードを考慮する必要があります:

#define gettext_noop(String) String
#define N_(String) gettext_noop (String)

N_は、_と同様、省略形です。GNU gettextpo/ディレクトリーにあるMakefileは、これらの省略形を認識するので、必要に応じて使うことができます。

今度はcatgetsを見てみましょう。主な問題点はプログラマー向けの機能にあります。彼は、翻訳可能な文字列ごとに、毎回異なる数字(または記号定数)を割り当てる必要があります。彼は重複したエントリー、重複したメッセージID、etc...にも注意を払わなければなりません。もしGNU gettextプログラムが提供するのと同じ品質をメッセージカタログにもたせたい場合、文字列にたいする説明コメントやソースコード中での場所をメッセージカタログに記述しなければなりません。これはほとんどMission: Impossibleでしょう。

しかしcatgetsの優位性を語る人たちが触れる点もいくつかあります。文字列内にある単語があり、その文字列が異なるコンテキストや他の言語で使われている場合に、その単語は異なる翻訳をもつことができます。以下に例を示しましょう:

printf ("%s: %d", gettext ("number"), number_of_errors)

printf ("you should see %d %s", number_count,
        number_count == 1 ? gettext ("number") : gettext ("numbers"))

この例では、"number"という文字列を2回翻訳する必要があります。たとえあなたがEnglishに類する言語を話さなくても、この単語が2つの文で異なる意味をもつかもしれないことに気づくでしょう。Germanでは、1番目にたいして"Anzahl"、2番目には"Zahl"と翻訳する必要があります。

これであなたはこのが難解な例だということに同意するでしょう。そしてあなたは間違っていません! では問題を正確に把握して、その問題がそれほど深刻ではないことにも気づくはずです。この問題は以下のようにして簡単に解決することができます:

printf ("%s %d", gettext ("number:"), number_of_errors)

printf (number_count == 1 ? gettext ("you should see %d number")
                          : gettext ("you should see %d numbers"),
        number_count)

わたしたちは、この方法で文字列の競合はすべて解決できると信じます。もし競合する文字列の一方を変更するのが困難なら、もう一方の文字列を少しだけ変更することも考慮できます。これを克服するのは不可能ではありません。

catgetsは、同じ元文字列にたいして異なる翻訳をもたせることができます。gettextでは同じ元文字列にたいして異なる翻訳をもたせることはできませんが、この種のあいまいさによる問題を解決する、よりスケーラブルな解決策があります。Ambiguitiesを参照してください。