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


15.5.18.5 文字列内挿の無効な使い方

Perlでは、変数による文字列の補間ができます。これはローカライズされるプログラムに恩恵をもたらしますが、問題を引き起こすこともあります。

以下のような文字列の生成はエラーを発生させます:

print gettext "This is the program $0!\n";

このような場合Perlは実行時に、関数gettext()の引数内の、変数$0を補間するでしょう。これにより、この引数は文字列定数ではなく文字列変数となります($0はグローバル変数で、実行されているperlのスクリプト名が保持されています)。補間はPerlが文字列引数をgettext()に渡す前に行われるので、文字列は実行時にのみ決定可能なスクリプト名に依存することになります。その結果、実行時に翻訳を見つけるのはほとんど不可能になります(メッセージカタログで補間された文字列が偶然見つかってしまった場合を除きます)。

そのためxgettextプログラムは、抽出された文字列の中に変数を見つけると、致命的なエラーとして解析を打ちきります。これは一般的に、このような補間文字列すべてをコンパイル時に安全に処理することができないからです。あなたが自分が何をしているか完全に知っている場合には、以下のようにしてこの挙動を回避できます:

my $know_what_i_am_doing = "This is program $0!\n";
print gettext $know_what_i_am_doing;

パーサーは、変数やその他の単語は認識しませんが、文字列と引用符の類だけなら認識するので、上記の文は許されます。しかし、多分あなたは元文字列をメッセージカタログに抽出するための、別の方法を見つける必要があるでしょう。

--extract-all(または-a)オプションを指定して呼び出すと、変数の補間ができるようになります。理論的な根拠: 一般的にはソースをインターナショナライズ用に準備するために、このオプションを使うでしょう。

補間される文字列・補間されない文字列と、引用符類の表現についての詳細は、‘man perlop’のmanpageを参照してください。以下は、(致命的なエラーとならない)安全な補間です:

以下のエスケープは、部分的には安全だとみなされます:

これらのエスケープは、文字列にASCII文字しか含まれていないときだけ、安全とみなされます。ASCIIで定義された範囲外の翻訳文字はlocale依存であり、実際には実行時しか処理できません。xgettextは、これらのlocale依存の翻訳を抽出時に処理しません。

修飾子\Qを除き、たとえこれらの翻訳が有効だとしても、一般的には無用であり、ソースがわかりにくくなるだけです。コンパイル時に翻訳が安全に処理できるなら、あなたも、意図することを同じように記述できるはずです。