Perl の locale 設定

下記のTwitterでの発言に関連してメモ。

perlの locale 設定は環境変数の $LANG によって決まるが、この設定が行われるのはインタプリタの初期化時(perl_construct())。

以下、perl.cより抜粋

void
perl_construct(pTHXx)
{
    ・
    ・
    ・

    JMPENV_BOOTSTRAP;
    STATUS_ALL_SUCCESS;

    init_i18nl10n(1);
    SET_NUMERIC_STANDARD();

#if defined(LOCAL_PATH_COUNT)

init_i18nl10n() が locale 設定を行う関数。init_i18nl10n() の実体は locale.c の Perl_init_i18nl10n()で、環境変数を読み出し、setlocale()を実行している。この処理は初期化時のみ実行されるため、Perlコード内で $ENV{LANG}を更新しても意味がない。

Perl コード内で locale 設定を変える場合は、以下のように POSIX の setlocale() を実行する。

use strict;
use warnings;
use POSIX qw(setlocale LC_ALL);

setlocale(LC_ALL, "C");

$ENV{LANG} の変更に合わせて locale 変更

思いつきで、$ENV{LANG} を更新すると自動的にsetlocale()するautolocaleというプラグマモジュールを作ってみた。

GitHub - hideo55/p5-autolocale: auto call setlocale when set $ENV{LANG}

使い方
use autolocale;

$ENV{LANG} = 'ja_JP.UTF-8';
#locale = ja_JP.UTF-8
...
{
    local $ENV{LANG} = 'C';
    #locale = C
    ...
}
#locale = ja_JP.UTF-8

レキシカルプラグマなので、レキシカルスコープでuse autolocale、no autolocale で自動設定の有効・無効化で可能。