NAME

perllocale - Perl locale handling (internationalization and localization)


DESCRIPTION

Perlは“(文字とはなにか)”、“この文字の大文字はなにか”、“これ らの文字のうちで最初にくるのは何か”のような言語に固有なデータの 概念をサポートしています。これらは特に英語以外の言語では重要なこ とです。が、これは英語でも同様で、A-Za-zがすべての“文字”を 定義していると考えてしまうのは単純すぎる(naïve)考えです。 Perlはまた、“.”以外の幾つかのキャラクターを小数点として扱うこ ともありますし、日付の表現は言語によって変わりうるものです。アプ リケーションにそういったユーザーの選択を考慮させるためのプロセス は、国際対応 internationalization と呼ばれます(これはしばしば i18nと省略されます)。アプリケーションを特定の選択に対応させる ことは地域対応 (localizationl10n)として知られています。

Perlは言語固有なデータを、“ロカールシステム”(locale system)と 呼ばれる標準メソッド(ISO C, XPG4, POSIX 1.c)を通して理解すること ができます。このロカールシステムは一つのプラグマ、一つの関数呼び 出し、幾つかの環境変数を使った、アプリケーション毎のコントローラ ーです。

注意: この機能はPerl 5.004で新たに追加されたもので、アプリケ ーションから陽にその使用を要求されない限り使われません。 Backward compatibilityを参照してください。一つの例外がwrite() で、これは常にカレントのロカールを使用します。NOTESを参照 してください。


PREPARING TO USE LOCALES

Perlアプリケーションがあなたのデータを、あなたの選択したロカール に正しくしたがって理解し提供するのであれば、以下のすべてが真 になっているはずです。

Perlアプリケーションをあなたの使うデータを特定のロカールで処理し たりするようにしたいのであれば、そのアプリケーションコードはプ ラグマ use locale を適切な場所に、そして以下に挙げる項目 の 少なくとも一つが真でなければなりません。


USING LOCALES


The use locale pragma

デフォルトでは、Perlはカレントのロカールを無視します。 use localeプラグマはPerlに、幾つかの操作において カレントのロカールを使うよう指示します。

LC_COLLATE, LC_CTYPEなどは、LOCALE CATEGORIESでさらに説 明されています。

no localeに出会うか、(use localeを囲む)ブロックの終 端に達するとデフォルトの動作に戻ります。

ロカール情報を使っている操作の結果である文字列は、ロカールが信頼 できない可能性があるかのように汚染(taint)されていることに注意してくだ さい。SECURITYを参照のこと。


The setlocale function

POSIX::setlocale()関数を使って、実行時に好きな回数だけ ロカールを切り替えることができます。

        # これはPerl 5.004より前では使えない
        require 5.004;

        # POSIXモジュールからロカール操作のツールセットをインポ
        # ートします。この例では、setlocale -- 関数呼び出し LC_CTYPE
        # -- 後述を使っています。
        use POSIX qw(locale_h);

        # 古いロカールを問い合わせ、セーブする
        $old_locale = setlocale(LC_CTYPE);

        setlocale(LC_CTYPE, "fr_CA.ISO8859-1");
        # LC_CTYPE now in locale "French, Canada, codeset ISO 8859-1"

        setlocale(LC_CTYPE, "");
        # LC_CTYPE now reset to default defined by LC_ALL/LC_CTYPE/LANG
        # environment variables.  See below for documentation.

        # 古いロカールに戻す
        setlocale(LC_CTYPE, $old_locale);

setlocale()の第一引数にはカテゴリー(category)を、第二引数には ロカール(locale)を与えます。カテゴリーはロカール特有の規則を 適用したいデータ処理の状況を指示します。カテゴリー名は LOCALE CATEGORIESENVIRONMENTに記述されています。ロカールはカスタマイズを 行うための、特定の言語の組み合わせ、国や地域、コードセットに関す る情報の集合の名前です。ヒントとしてロカールの名前付けに注目して ください。すべてのシステムがこの例のようにロカールに名前を付けて いるわけではありません。

第二引数が省略されていて、さらにカテゴリーがLC_ALL以外の場合、こ の関数はカテゴリーに対するカレントロ カールの名前からなる文字列を返します。この値を、後で行うsetlocale() の呼び出しでの第二引数として使うこともできます。第二引数が与えら れていて、かつそれが正当なものであれば、この関数はカレントのロカ ール値を返します。この値はsetlocale()に対する呼び出しで使うこと ができます(一部の実装では、この戻り値は第二引数を与えたときと異 なる場合があります。-- これは与えた引数のエイリアスと考えられま す)。

If a second argument is given and it corresponds to a valid locale, the locale for the category is set to that value, and the function returns the now-current locale value. You can then use this in yet another call to setlocale(). (In some implementations, the return value may sometimes differ from the value you gave as the second argument--think of it as an alias for the value you gave.) =cut

カテゴリーがLC_ALLで、第二引数が与えられなかった場合には その結果は処理系に依存するものとなります。 ロカールの名前を連結したものか(セパレーターはこれまた処理系依存のもの)、 単一のロカール名となります。 詳しくはsetlocale(3)をあたってください。

第二引数が与えられていてそれが正しいものであれば、そのカテゴリーに対する ロカールは値に応じて設定され、関数は新しいロカール値を返します。 この戻り値を別のsetlocale()のために使うこともできます (一部には、この戻り値が第二引数として与えるものとは異なるもので あるという実装もあります。これはあなたの与えた名前の別名として 考えられます)。

例に示したように、第二引数が空文字列であった場合にはカテゴリーの、 対応する環境変数によりデフォルト指定されるロカールが返されます。 一般的にはこの結果は、Perlが起動したときに強制的にデフォルトとし て設定された値です。アプリケーションが起動した後での環境変数の変 更が認識される/されないは、使用しているCライブラリに依存し ます。

第二引数が正しいロカールを表わしていない場合、 カテゴリーに対するロカールは変更されず、関数はundefを返します。

カテゴリーに対する詳細な情報は、setlocale(3)を参照してくださ い。


Finding locales

ロカールを見つける

ロカールが使えるシステムであれば、使用可能なロカールがどういったもの であるかどうかをL<setlocale(3)>で調べてみてください (SEE ALSOセクションを探してください)。それがダメだったら、 以下のコマンドを試してみてください。

        locale -a

        nlsinfo

        ls /usr/lib/nls/loc

        ls /usr/lib/locale

        ls /usr/lib/nls

        ls /usr/share/locale

そして、そこに以下に挙げたものと似たものがあるかどうかを 確かめてください。

        en_US.ISO8859-1     de_DE.ISO8859-1     ru_RU.ISO8859-5
        en_US.iso88591      de_DE.iso88591      ru_RU.iso88595
        en_US               de_DE               ru_RU
        en                  de                  ru
        english             german              russian
        english.iso88591    german.iso88591     russian.iso88595
        english.roman8                          russian.koi8r

残念ながら、setlocale()を呼び出すインターフェースが既に標準化さ れているのにも関らず、ロカールの名前であるとかそれがコンフィグレ ーションされるディレクトリはまだなのです。名前の基本形式は language_territory.codeset ですが、末尾の部分は 常にある訳ではありません。languagecountryは 通常はISO 3166ISO 639という標準による、 言語や国を二文字に略したものになります。codesetの部分は しばしばキャラクターセット ISO 8859のバリエーションとなります。 たとえば、``Western codeset''と呼ばれる ISO 8859-1は 西欧におけるエンコードとして用いることができます。繰り返しますが、 一つの標準の名前であってさえ、記述するには複数の方法が存在するのです。 残念ながら。

“C”と“POSIX”という二つの特殊なロカールがあります。現時点では、 これら二つは同じロカールとなります。その違いは主に、前者がCの標 準により決められたものであるのに対して、後者がPOSIXの標準で決め られているものであるという点にあります。これらの規格が決めている ことは、環境変数にあるロカール情報がない状態でのプログラム起動時 のデフォルトのロカールです(デフォルトのデフォルトロカールです)。 その言語は (アメリカ)英語であり、そのキャラクターセットはASCIIと なります。

注意:すべてのシステムが“POSIX”ロカールを持っているわけでは ありません(すべてのシステムがPOSIXに準拠しているわけではありませ ん)。ですから、このデフォルトロカールを指定するのが必要なときに は“C”を使います。


LOCALE PROBLEMS

ロカールの問題

Perlを実行したときに以下のようなメッセージを見たことがあるかもしれません:

        perl: warning: Setting locale failed.
        perl: warning: Please check that your locale settings:
                LC_ALL = "En_US",
                LANG = (unset)
            are supported and installed on your system.
        perl: warning: Falling back to the standard locale ("C").

これは、あなたのロカールの設定が、LC_ALLが“En_US”でありLANGが存在しているが 値を持っていないということを意味します。Perlはあなたを信じようとしたの ですができなかったのです。その代わりに、Perlはロカール設定をあきらめて、 デフォルトである``C''ロカールに戻ったのです。これは通常は あなたのロカール設定が間違っているせいであり、聞いたことのない ロカールであったり、あるいはあなたのインストールに問題があったのだろう (例えば、一部のシステムファイルが壊れていたとか、なかったとか)ということです。 以下で述べるのは、この問題を手っ取り早く一時的に修復するものです。


Temporarily fixing locale problems

二つの(一時的な)対応策とは、ロカールに関する矛盾を無視するように するというものと、Perlをデフォルトロカール``C''で実行するというものです。

Perl起動時の問題は、環境変数PERL_BADLANGにゼロ、たとえば “0”を設定することによって回避することができます。この方法は 問題をカーペットの下に押し込むだけのことです: つまり、Perlが何か間違ったことを見つけたとしても Perlを黙らせておくというものです。 もし後でロカールに依存した変な振る舞いがあったとしても 驚かないでください。

環境変数LC_ALLに``C''を設定することにより、Perlはロカール``C''の下で も実行することができます。このやり方はPERL_BADLANGよりは多少まと もなものですが、それでもLC_ALL(もしくは他のロカール変数)を設定す るということはPerl以外のプログラムにも影響を及ぼします。特に、Perl の内側で実行される外部プログラムはこの変更に影響を受けることになります。 新しい設定を恒久的なものにしたいというのであれば、あなたが実行する プログラム全てがこの変更に影響を受けることになります。 関係する環境変数の完全なリストはENVIRONMENTを参照してください。 また、Perlにおけるそれらの効果についてはUSING LOCALESを参照 してください。他のプログラムに対する影響は簡単に避けられます。 たとえば、変数LC_COLLATEはあなたのsortプログラム (もしくは'レコードを'アルファベットによって アレンジするプログラム)に影響を及ぼします。

これらの変数に対する変更を一時的に行ってテストすることができます。 そして新しい設定が助けになるものであればその設定をシェルのスタートアップ ファイルに追加するのです。詳細はあなたの使っているシステムのドキュメント を調べてみてください。Bourne シェルに似たシェル(sh, ksh, bash, zsh) であれば以下のようになります:

        LC_ALL=en_US.ISO8859-1
        export LC_ALL

これは、コマンドが参照するロカールを``en_US.ISO8859-1'' にしています。 Cシェルライクなもの(cshtcsh)の場合には

        setenv LC_ALL en_US.ISO8859-1

となります。あなたがシェルについて良く知らないというのであれば、 あなたのおそばのヘルプデスク等に訊ねてみてください。


Permanently fixing locale problems

ロカール問題を恒久的に修正する

First, see earlier in this document about Finding locales. That tells how to find which locales are really supported--and more importantly, installed--on your system. In our example error message, environment variables affecting the locale are listed in the order of decreasing importance (and unset variables do not matter). Therefore, having LC_ALL set to ``En_US'' must have been the bad choice, as shown by the error message. First try fixing locale settings listed first. =cut

時間はかかるけれども優れた修正方法は、あなたの環境の間違って いる部分を正しくするというものです。システム全体での間違いは あなたの使っているシステムの、フレンドリーな管理者の助けを 必要とするでしょう。

まず最初にこのドキュメントのFinding localesを参照してください。 そこにはあなたの使うシステムで実際にサポートされているロカール、 そしてもっと重要なインストールされているロカールを見つけだす方法が解説 されています。私たちが使ったエラーメッセージの例では、 環境変数は重要度の高いものから低いものへという順になっています。 したがって、LC_ALLを“En_US”に設定することは良くない選択であり、 これはエラーメッセージにも現れています。まず最初にリストの最初に あるロカール設定を修正します。

次に、もしあなたがリストアップのコマンドを使って得たものが 本当に“En_US”のようなもの(プリフィックスのマッチは数えず、 太小文字の違いは考慮します)であれば、あなたが使っているロカール名に 対応するものが システムに正しくインストールされていればOKです。 この場合、Permanently fixing system locale configurationを参照してください。


Permanently fixing your locale configuration

あなたのロカール設定を恒久的に修正する

これは

        perl: warning: Please check that your locale settings:
                LC_ALL = "En_US",
                LANG = (unset)
            are supported and installed on your system.

のようになったが、“En_US”が先に挙げたコマンドによってリスト 中になかった場合です。“en_US.ISO8859-1”のようなものを見たかも 知れませんが、まったく同一のものではなかったのでしょう。 この場合、コマンドで挙げられたものにマッチするロカールで実行 してみてください。ロカール名のマッチングルールは 少々はっきりしないものです。それは、この分野に関する標準が 弱いものであるからです。一般的なルールについては Finding localesをもう一度見てください。


Fixing system locale configuration

システムのロカール設定を修正する

システム管理者にコンタクトをとって、あなたの得たエラーメッセージそのままを レポートして、今ここまで読んできたことを説明してください。 システム管理者はシステムのロカール設定についてどこがどう間違っているか を理解できるはずです。標準化がなされていないので、コマンド名などに 関してFinding localesのセクションは残念ながら少々あやふやなものに なっています。


The localeconv function

POSIX::localeconv()関数は、カレントの LC_NUMERICLC_MONETARY で指定されるロカール依存の数値書式の情報を取り出します(ある特定 のカテゴリーのカレントロカールを知りたいだけなのなら、 POSIX::setlocale()を引数一つで使います。The setlocale function を参照してください)。

        use POSIX qw(locale_h);

        # ロカール依存の情報のハッシュへのリファレンスを取得
        $locale_values = localeconv();

        # ソートしたリストの値を出力
        for (sort keys %$locale_values) {
            printf "%-20s = %s¥n", $_, $locale_values->{$_}
        }

localeconv()は引数を取らず、戻り値としてハッシュに対するB<リファレンス> を返します。このハッシュのキーはdecimal_pointthousands_sep のように整形された変数名であり、格納されている値はそのキーに対応 する値です。ある実装が提供しているであろうすべてのカテゴリーをリ ストアップしている長いサンプルは POSIX (3) を参照 してください。しかしながら、一部のものが多かったり少なかったする かもしれません。ロカールを問い合わせるジョブの関数のようにuse locale する必要がないことに注意してください。localeconv()は常にカレント のロカールを監視しています。

以下の例は、コマンドラインで渡されたパラメーターを カレントのロカールにおける正しい書式に書きなおすというものです。

        # 前の例のコメントを参照
        require 5.004;
        use POSIX qw(locale_h);

        # ロカールの数値書式パラメーターを取得する
        my ($thousands_sep, $grouping) =
             @{localeconv()}{'thousands_sep', 'grouping'};

        # 値が設定されていなければデフォルト値を適用
        $thousands_sep = ',' unless $thousands_sep;

        # grouping とmon_groupingは小整数のパック済みリストになっ
        # ています。これはgrouping (thousand_seps と mon_thousand_seps
        # はグループを分けるものです)の数と金銭に関するものの指定
        # を行っています。その整数の意味はこうです: 255はグルーピ
        # ングしないことを意味します。1から254はカレントのグルーピ
        # ングで使用する数値を意味します。グルーピングは右から左へ
        # (下位桁から上位桁)と適用されます。下の例では最初のグルー
        # ピング以外は使わないことによってこれを避けています。

        if ($grouping) {
            @grouping = unpack("C*", $grouping);
        } else {
            @grouping = (3);
        }

        # カレントのロカールのためにコマンドラインを整形する
        for (@ARGV) {
            $_ = int;    # 整数でない部分を取り除く
            1 while
            s/(¥d)(¥d{$grouping[0]}($|$thousands_sep))/$1$thousands_sep$2/;
            print "$_";
        }
        print "¥n";


LOCALE CATEGORIES

以下のセクションでは、基本的なロカールカテゴリーの説明をします。 先の例のように、複数の基本カテゴリーを扱うことができる幾つかの 組み合わせカテゴリー(combination categories)があります。 この事に関する詳細は、ENVIRONMENT を参照してください。


Category LC_COLLATE: Collation

use localeのスコープの内側にあるとき、Perlはアプリケーショ ンで使用するキャラクターの照合(順番)を決定するために環境変数 LC_COLLATEを参照します(ラテンアルファベットでは‘b’は`a'に 続くものですが、‘á’ や ‘å’ はどこに置かれるの でしょう?)。また、英語では'color'は'chocolate'よりも後に なりますが、スペイン語ではどうでしょう?

以下の照合は全て意味あるものであり、“use locale”をすれば 直面することもあるでしょう。

        A B C D E a b c d e
        A a B b C c D d D e
        a A b B c C d D e E
        a b c d e A B C D E

以下のコード片はカレントのロカールにおける alphanumericキャラク ターをそのロカールでの順序で出力するものです。

        use locale;
        print +(sort grep /¥w/, map { chr() } 0..255), "¥n";

これと、陽にロカールを無視するように指示したときの キャラクターとを比較してみてください。

        no locale;
        print +(sort grep /¥w/, map { chr() } 0..255), "¥n";

この、マシン本来(machine-native)の照合 (同じブロックの前のほうで use localeをしていない方) は生のバイナリデータのソートに用いるもので、 最初の例で使ったロカール依存の照合は通常のテキストに使うのに 便利です。

USING LOCALESで述べたように、cmpuse localeが有効な ときにはカレントの照合ロカールに従って比較を行いますが、 この結果が等しいと出た場合にはバイト毎の比較に逆戻りします。 この逆戻りが嫌ならば、POSIX::strcoll()を使うことができます。

        use POSIX qw(strcoll);
        $equal_in_locale =
            !strcoll("space and case ignored", "SpaceAndCaseIgnored");

$equal_in_locale は照合ロカールが空白キャラクタを完全に無視し、 大小文字の区別を無視するような辞書に似た順序付けを 指定している場合には真になるでしょう。

“ロカールにおける等価性”の検査を他のものに対して行いたい(一つ の)文字列があるときにあなたは、POSIX::strxfrm()をC<eq>と一緒に使 うことによって多少の効率アップができると考えるかもしれません。

        use POSIX qw(strxfrm);
        $xfrm_string = strxfrm("Mixed-case string");
        print "locale collation ignores spaces¥n"
            if $xfrm_string eq strxfrm("Mixed-casestring");
        print "locale collation ignores hyphens¥n"
            if $xfrm_string eq strxfrm("Mixedcase string");
        print "locale collation ignores case¥n"
            if $xfrm_string eq strxfrm("mixed-case string");

strxfrm()は文字列を引数にとり、それを同様の変換を加えられた文字 列とのバイト毎の比較に使えるような文字列に変換します。 ``Under the hood'', ロカールに影響されたPerlの比較演算子は strxfrm()を両オペランドのために呼び出して、その後でバイト毎の比 較を、変換された文字列に対して行います。strxfrm()を陽に呼び出す こととロカールに影響されない比較を行うことで、上記の例は変換をセ ーブするようになります。実際にはこれは何もセーブしません。perlの 魔法(perlgutsを参照)は、比較の際に必要であれ ば最初に変換された文字列を生成し、それからそれが再び必要になるま で取っておくのです。cmpを使って書き直したサンプルは可能な限り 早く実行されます。また、文字列に埋め込まれているナルキャラクター にも対処します。strxfrm()を直接呼び出した場合、ナルは終端子とし てみなされます。そして、変換後の文字列がシステムを越えて使えるよ うなものであると期待してはいけません。また、あるオペレーティング システムのバージョンで作ったものが次のバージョンでも同様であると いうことも期待してはいけません。一言でいうと、strxfrm()を直接呼 び出してはいけない。ということです。Perlに呼び出しをさせましょう。

注意: 幾つかのサンプルでは、必要がないのでuse localeがありません。 strcoll()やstrxfm()はロカール依存の結果しか生成しませんので、 常にLC_COLLATEロカールを参照するのです。


Category LC_CTYPE: Character Types

use localeのスコープにあるとき、PerlはLC_CTYPEロカール の設定に従います。これは、アプリケーションのアルファベットキャラ クターの取り扱いを制御します。これはPerlのアルファベット及び数字 を表わす正規表現のメタ表記 ¥wに影響します(正規表現については perlreを参照してください)。LC_CTYPEのおかげで、ロカール設 定に依存した'æ', 'ð', 'ß', 'ø' のようなキャラクターが¥wキャラクターとして認識できるのです。

LC_CTYPE ロカールはまた、小文字と大文字との間の相互変換に使わ れるマップを提供します。これはcase-mapping関数lc(), lcfirst, uc(), ucfirst()とダブルクォートで囲まれた文字列の中での¥l, ¥L, ¥u, <¥U> によるcase-mapping interpolation、そしてs///によ る置換、i修飾子を使った(大小文字を無視する)正規表現パターンマ ッチングに影響を及ぼします。

さらに、LC_CTYPEはPOSIXのキャラクタクラステスト関数、isalpha(), islower() などにも影響を及ぼします。たとえば、“C”ロカールを7bit のスカンジナビアのものにしたとすると、多分あなたは驚くことになる でしょうが、``|'' がispunct()クラスからisalpha()クラスに移動するの です。

注意: 不正な、あるいは意地の悪い(malicious) LC_CTYPEロカー ルの定義は、不適切なキャラクターをalphanumericであるとみなしてし まう可能性があります。(アクセント記号のない)文字や数字の厳密なマ ッチング、例えばコマンド文字列のロカールを警戒するアプリケーショ ン(locale-aware application)はno localeブロックの内側で¥w を使うべきなのです。SECURITYを参照してください。


Category LC_NUMERIC: Numeric Formatting

use localeのスコープの中にあるとき、PerlはLC_NUMERIC ロカール情報を参照します。これはアプリケーションがprintf(), sprintf(), write()といった関数を使ったときに数値をどのように整形 するかということを制御するものです。文字列から数値への変換には、 関数 POSIX::strtod() も影響を及ぼします。大部分の実装では、小数 点を表わすキャラクターを '.' から ',' へと変更するだけの効果し かありません。これらの関数は三桁毎の区切りなどについては考慮しま せん(この事について心配があるのならL<The localeconv function> を 参照してください)。

print()により生成された出力はカレントロカールの影響を 決して受けません。この関数は use localeやC<no locale>のいずれにも影響を受けず、 “C”ロカールでprintfを使ったときと同じ結果を出力するのです。 Perlの、数値と文字列との間の内部的な変換はこれと同じです。

        use POSIX qw(strtod);
        use locale;

        $n = 5/2;   # 数値の2.5を$nに代入

        $a = " $n"; # ロカール独立の、文字列への変換

        print "half five is $n¥n";       # ロカール非依存の出力

        printf "half five is %g¥n", $n;  # ロカール依存の出力

        print "DECIMAL POINT IS COMMA¥n"
            if $n == (strtod("2,5"))[0]; # ロカール依存の変換


Category LC_MONETARY: Formatting of monetary amounts

標準CではLC_MONETARYカテゴリーを定義していますが、その内容に 影響される関数はありません。 (Those with experience of standards committees will recognize that the working group decided to punt on the issue.) 結果として、Perlはこれに注意を払いま せん。もし本当に LC_MONETARYを使いたければ、自分でその内容を 問い合わせることができます。(The localeconv function を参照し てください)。そして返ってきた情報をアプリケーションの currency amountsの整形に使います。しかし、この情報を取得することはできる でしょうが、大量かつ複雑で、要求に対して本当にあったものではない でしょう。金銭に関する書式は手におえない代物なのです。


LC_TIME

人が読みやすい、整形された日付/時刻文字列を作り出す POSIX::strftime() によって生成された出力はカレントのLC_TIMEロカールに影響を受け ます。したがって、フランスのロカールでは、%B書式指定子(省略の ない月の名前)を一年の最初の月に対して使ったときの結果は、“janvier” となります。以下の例は、カレントロカールにおける長い月名のリストを 得るものです。

        use POSIX qw(strftime);
        for (0..11) {
            $long_month_name[$_] =
                strftime("%B", 0, 0, 0, 1, $_, 96);
        }

注意: use localeはこの例では必要ではありません。strftime()は 常にカレントのLC_TIMEロカールを参照し、ロカール依存の結果のみ を生成します。


Other categories

残ったロカールカテゴリー LC_MESSAGES (別の特定の実装により提 供されているでしょう)は、現在のPerlでは標準のPerl配布パッケージ にはないエクステンションから呼ばれるライブラリ関数が使っている可 能性を除けば、使っていません。


SECURITY

Perlのセキュリティに関する事項の主な議論はperlsecにありますが、 Perlのロカールの扱いに関する議論はそれがあなたのロカール依存のセ キュリティ事項に対して注意していなければ不完全です。ロカール(特 権のないユーザーが自分のロカールを構築するのを許すようなシステム の特性)は信用できないものなのです。意地の悪い(もしくは単に壊れた) ロカールはロカールを使うアプリケーションを予期できない結果にする 可能性があります。以下に幾つかの可能性を挙げます。

このような危険は、ロカールシステムに特有のものではありません。意 地の悪い変更を通して同じような攻撃を受けるようなアプリケーション 環境のあらゆる状況が対象となります。同様に、これはPerlに固有なも のでもありません。環境を考慮するようなプログラムを書くことのでき るあらゆるプログラミング言語で同様の危険性があるのです。

perlは例示したようなすべての可能性からあなたを守ることはできません。 あなた自身の用心に代り得るものはないのです。しかし、use locale が有効であるとき、Perlは tainting機構(perlsecを参照)をlocale に依存した結果であり、信用できないかもしれない文字列に注意するた めに使用します。以下は、ロカールにより影響を受ける可能性のある演 算子や関数の汚染される振る舞いのまとめです。

Comparison operators (lt, le, ge, gt and cmp):

スカラーの真/偽(もしくは未満/等しい/越えている)の結果は 決して汚染されません。

Case-mapping interpolation (with ¥l, ¥L, ¥u or ¥U)

展開されたものが含まれる文字列はuse localeが有効な 場合には汚染されます。

Matching operator (m//):

スカラーの真/偽の結果は決して汚染されません。

配列コンテキストの結果や、$1などから派生したサブパターンは use localeが有効であるときには汚染されます。そして、¥w (alphanumericキャラクターにマッチする)、¥W (alphanumericキャ ラクター以外にマッチする)、¥s (空白キャラクター)、¥S (空白 でないキャラクター)を含む正規表現サブパターンも同様です。マッチ した結果を保持する変数、$&、$`(マッチした部分より前)、$'(マッチ した部分より後)、$+ (最後にマッチしたもの)、そして ¥w¥W¥s¥S、を含む正規表現も、use localeが有効であるときに は汚染されます。

Substitution operator (s///):

マッチ演算子と同じ振る舞いをします。また、=‾の左オペランドは use localeが有効であるときに、¥w, ¥W, ¥s, ¥Sを含 んでいたりC<¥l>, ¥L,¥u, ¥Uを使ったcase-mappingを使ってい る正規表現に基づいた置換の結果として文字列が変更された場合に、汚 染が生じます。

In-memory formatting function (sprintf()):

use localeが効力を持っているときに、結果は汚染されます。

Output formatting functions (printf() and write()):

成功/失敗の結果は決して汚染されません。

Case-mapping functions (lc(), lcfirst(), uc(), ucfirst()):

use localeが効力を持っているときに、結果が汚染されます。

POSIX locale-dependent functions (localeconv(), strcoll(), strftime(), strxfrm()):

結果は決して汚染されません。

POSIX character class tests (isalnum(), isalpha(), isdigit(), isgraph(), islower(), isprint(), ispunct(), isspace(), isupper(), isxdigit()):

真/偽の結果は決して汚染されません。

三つの例を使って、ロカール依存の汚染(locale-dependent tainting) を説明します。最初のプログラムはそのロカールを無視して、実行され ません。汚染検査が有効であるときには、コマンドラインから直接とっ た値を出力ファイル名として使うことはできません。

        #/usr/local/bin/perl -T
        # 汚染検査付きで実行する

        #コマンドラインの健全性の検査を省略…
        $tainted_output_file = shift;

        open(F, ">$tainted_output_file")
            or warn "Open of $untainted_output_file failed: $!¥n";

このプログラムは、汚染された値を正規表現を通して“洗濯”(laundering) することにより実行できるようにできます。以下に挙げる二番目の例は、 これもロカール情報を無視しています。実行されると、コマンドライン にある名前のファイルを可能であれば作成します。

        #/usr/local/bin/perl -T

        $tainted_output_file = shift;
        $tainted_output_file =‾ m%[¥w/]+%;
        $untainted_output_file = $&;

        open(F, ">$untainted_output_file")
            or warn "Open of $untainted_output_file failed: $!¥n";

これを、非常に良く似てはいるが、ロカールを使ったプログラムと 比較してみてください。

        #/usr/local/bin/perl -T

        $tainted_output_file = shift;
        use locale;
        $tainted_output_file =‾ m%[¥w/]+%;
        $localized_output_file = $&;

        open(F, ">$localized_output_file")
            or warn "Open of $localized_output_file failed: $!¥n";

この三番目のプログラムは、$&が汚染されているので実行に失敗します。 これはuse localeが有効であるときの¥wを含んだマッチングによ る結果です。


ENVIRONMENT

PERL_BADLANG

Perlが起動時にロカールの設定に失敗した場合に警告を出すのを抑制で きる文字列です。オペレーティングシステムのロカールサポートがなん らかの理由でなかったり、壊れていたりするとき、あるいは環境変数に 設定したロカールの名前を間違えていた場合に発生します。もしこの変 数が存在していないとか、あるいはその値が評価すると0にならないよう なもの、つまり“0”や“”でない場合に、Perlはロカールの設定に失敗 するとメッセージを出力します。

注意: PERL_BADNLANGは警告メッセージを出さないようにするだけで す。このメッセージはあなたの使うシステムのロカールサポートになに かの問題があるということを伝えるものですから、あなたは問題がなん なのかを確かめるべきでしょう。

以下の環境変数はPerlに特有のものではなく、アプリケーションのデー タの扱いを制御するための標準的な(ISO C, XPG4, POSIX 1.c) setlcaole()メソッドの一部分です。

LC_ALL

LC_ALL はロカールの環境変数のすべてをオーバーライドします。 もしこの環境変数が設定されていると、他のすべての環境変数を オーバーライドします。

LANGUAGE

注意:LANGUAGEはGNUの拡張で、GNU libcを使っているときに のみ効果があります。Linuxを使ったときなどがこれに該当します。 あなたが“商用の”UNIXを使っているのであればGNU libcは使われて いないでしょうし、LANGUAGEは無視することができます。

LANGUAGEを使った場合には、 コマンドからの情報、警告、エラーといった メッセージの言語に影響を及ぼします(言い換えるとLC_MESSAGESと 似ています)が、LC_ALLよりも優先順位は下です。さらに、 これは単一の値ではなくて言語(ロカールではありません)の、 “:”で連結された“パス”になっています。より詳しい情報は GNU gettextライブラリのドキュメントを参照してください。

LC_CTYPE

LC_ALLがないときに、LC_CTYPEはキャラクタータイプのロカール を選択します。LC_ALLもC<LC_CTYPE>もない場合、LANGがキャラ クタータイプのロカールを選択します。

LC_COLLATE

LC_ALLがないときに、LC_COLLATEは照合(ソーティング)ロカール を選択します。LC_ALLLC_COLLATEの両方がない場合、LANG が照合ロカールを選択します。

LC_MONETARY

LC_ALLがないときに、LC_MONETARYは monetary formatting ロカ ールを選択します。LC_ALLLC_MONETARYの両方ともない場合、 LANGが monetary formatting ロカールを選択します。

LC_NUMERIC

LC_ALLがないときに、LC_NUMERICは数値表記のロカール(numeric format locale)を選択します。LC_ALLLC_NUMERICの両方ともが ない場合、LANGが数値表記を選択します。

LC_TIME

LC_ALLがないときに、LC_TIMEは日付・時刻表記のロカール(date and time formatiting locale)を選択します。LC_ALLLC_TIMEが 両方ともない場合、LANGが日付・時刻表記のロカールを選択します。

LANG

LANGは“catch-all”なロカール環境変数です。 これに値が設定されている場合、LC_ALLも、各カテゴリーの LC_...も設定されていないときの最後の参照場所として 使われます。


NOTES


Backward compatibility

5.004より前のバージョンのPerlでは、ほとんどロカール情報を無視 して、たとえプログラム環境が別のものを指示していたとしても常に "C"ロカール(The setlocale functionを参照)が強制されている かのように振る舞っていました。デフォルトでは、Perlは今でもこのよ うに動作するので、上位互換性(Backward compatibility)があります。 Perlアプリケーションをロカール情報に注目するようにしたいのなら、 use locale プラグマ(The use locale pragmaを参照)をB<使 わなければなりません>。

5.002から5.003のPerlは、使用可能である場合にはLC_CTYPEの情報 を使っていました。つまり、¥wはロカールの環境変数に従った文字 を理解していたのです。問題は、Cライブラリがロカールをサポートし ている場合にはPerlがそれを使ってしまい、ユーザーがこの機能を制御 できないということでした。


I18N:Collate obsolete

5.004より前のバージョンのPerlでは、ロカール毎の照合はI18N::Collate ライブラリモジュールを使うことで可能でした。このモジュールは現在、 やや時代遅れ(mildly obsolete)となっていて、新しいアプリケーショ ンでは使用を避けるべきものです。現在、LC_COLLATE機能はPerlの コア言語に統合されました。スカラーデータのロカール固有の比較は use localeを使うことで完全に行なわれます。このため、 I18N::Collateのスカラーリファレンスを使ってお手玉(juggle)する 必要はもはやないのです。


Sort speed and memory use impacts

ロカールによる比較とソートは通常、デフォルトのソートに比べ二倍か ら四倍遅くなります。また、メモリの使用量も増大します。Perlのスカ ラー変数がロカールの照合規則を使ったなんらかの文字列比較やソート の中で現れると、それによって以前より三倍から十五倍の時間を要する ようになります(実際のところの乗数は文字列の内容、オペレーティン グシステム、ロカールに依存します)。この性能ダウンは、Perlによる ものよりもオペレーティングシステムのロカールシステムの実装による ものが顕著に現れます。


write() and LC_NUMERIC

フォーマットはPerlで、プログラムのロカールから来る情報を無条件に 使用する唯一の部分です。プログラムの環境でLC_NUMERICロカールが指 定されていれば、書式指定された出力にある小数点のキャラクターは常 にそこで指定されたものが使われます。書式指定された出力はuse locale によって制御することはできません。なぜなら、このプラグマはプラグ マのあるブロック構造に結び付けられていて、また、歴史的経緯によっ てフォーマットはブロック構造の外側に存在しているからなのです。


Freely available locale definitions

ftp://dkuug.dk/i18n/WG15-collectionにロカール定義の大規模なコ レクションがあります。これがサポート無しのものであり、どんな目的 にも適合するとは主張していないものであることに注意すべきです。あ なたの使うシステムがロカール機能のインストールを許しているのであ れば、この場所で便利な定義を見つけることができるでしょうし、ある いは自分でロカールを定義する基礎となるようなものを見つけられるか もしれません。


I18n and l10n

``Internationalization'' (国際化、国際対応)はその最初と最後の文字、 そしてその間にある文字数からB<i18n>としばしば略されます。同様の やり方で、“localization”もしばしばl10nと省略されます。


An imperfect standard

国際対応は標準Cや標準POSIXに定義されているように、不完全で、扱い にくく、粒度が大きすぎると酷評されます(ロカールは、単一のスレッ ドであるとか、ウィンドウグループといったものに対して適用するのが 便利であるときにもプロセス全体に適用されます)。また、標準化グル ープに似て、世界を国に分割しようとする傾向があります。しかし現在 のところ、これが私たちの手にある唯一の標準なのです。これはバグと して解釈できるかもしれません。


BUGS


Broken systems

幾つかのオペレーティングシステムにおける環境でのロカールサポート は、おかしなもので、それに対処したりPerlから使えないようなもので す。そういった不完全なものは、use localeが有効になったときに Perlを不可思議なハングアップに導いたり、コアダンプをさせたりしま す。このようなシステムに直面した場合、詳しい状況を <perlbug@perl.com>にレポートし、そして使用しているシステムの ベンダーに不満を伝えてください。問題の幾つかに対するバグフィック スがされているかもしれません。そういったバグ修正は、オペレーティ ングシステムのアップグレードと呼ばれることがあります。


SEE ALSO

POSIX (3)

POSIX (3)

POSIX (3)

POSIX (3)

POSIX (3)

POSIX (3),

POSIX (3)

POSIX (3)

POSIX (3),

POSIX (3)

POSIX (3)

POSIX (3),

POSIX (3)

POSIX (3)

POSIX (3),

POSIX (3)


HISTORY

Jarkko Hietaniemi's original perli18n.pod heavily hacked by Dominic Dunlop, assisted by the perl5-porters. Prose worked over a bit by Tom Christiansen.

Last update: Thu Jun 11 08:44:13 MDT 1998