localeってなんだっけ
最近ArchLinuxを使うべくいろいろ勉強しています。
その一環としてあまり気にしていなかったlocaleについて調べてみました。
localeは国や地域などの言葉・文字・単位・日付形式などを定義したものです。このlocaleを切り替えることでLinuxは国際化ができるようになっています。
ちなみに国際化はinternationalizationまたはinternationalisationで、単語としては長すぎるのでi18n
と略されます。iとnの間に18文字あるからなんですね。
@MINOはいままであんまり考えなしに、en_US
とja_JP
を有効にしていましたが、そもそもlocaleとはどんな風に定義されているの気になりますよね(よね?)
localeを構成する仕組み
localeは仕組みとして、以下のようなファイルやプログラムから生成されます。
コンパイルされてオブジェクトを使うようになっているんですね。
localeを構成するファイルやプログラミング
localeのリスト | /etc/locale.gen |
---|---|
localeをコンパイルするコマンド | /usr/bin/localedef |
localedefを使いやすくするシェルスクリプト | /usr/bin/locale-gen |
localeのソースファイル | /usr/share/i18n/locales/ |
localeで使用される文字コードにUCS変換対応表 | /usr/share/i18n/charmaps |
コンパイルされたlocaleオブジェクトファイル(実体) | /usr/lib/locale/locale-archive |
localeのコンフィグ | /etc/locale.conf |
localeを有効にするには
一応localeの設定の方法を簡単に整理しておきましょう。
locale.def
で有効にしたいlocaleをアンコメントするlocaledef
でlocaleをコンパイルする- もしくは
locale-gen
があればlocale-gen
でコンパイルする - システムのlocaleの設定は
locale.conf
を適切に設定する - ユーザー単位は
.bashrc
にlocaleを設定する
ちょっと localeのソースファイルをのぞいてみる
日本のlocaleソースファイルを見てみます。以下にあるかと思います(Ubuntu/debian,Arch)
/usr/share/i18n/locales/ja_JP
文字の定義はどんな感じ?
このファイルにはいろいろ定義されていますが、とりあえず文字の定義を見てみましょう。
37行あたりにLC_CTYPE
という項目があると思います。そこが文字の定義になっています。
jhira
とかjkata
とかいう項目があるかとおもいますが、それぞれひらがな・カタカナの定義です。
日本語では数字・記号・ひらがな・カタカナ・漢字・アルファベット(ローマ字)を使います。
それぞれの文字にはコードセット内でコードが決められているので、localeでは使うコードの定義を行っています。
そのコードが
などと記述されています。
英語だと文字数が少ないですが、ひらがな・カタカナはともかく漢字がしこたまあるので、これを定義しているコードもしこたまあります。
実際ja_Jp
はjkanji
の項目にしこたま漢字のコードが記述されているので相当長いです。
ja_JP
は15000行程度ありますが、en_US
は200行に届きません。
そのためロケールアーカイブファイルはそのlocaleによって容量がかなり違いマス。
ロケールアーカイブファイルのなどのコードはなにを示している?
これらのコードはUCS(Universal Multiple-Octet Coded Character Set)
のコードです。
Unicode
と互換性があるそうなのでUnicode
といってもいいのかもしれません。
UCS
は4byte
にて文字を管理する文字集合(UCS-4
とよばれます)です。約21億文字の表現が可能です。すごい大きいです。
世の中に21億文字もユニークな文字が存在しているかどうかはわかりませんが、とにかく文字という文字はこのUCS
で体系コードとして整理できます。
いろいろな文字コードが存在しますが、このUCS
は事実上、地球に存在する(現在使われている)文字がすべてインデックスできるので、このUCS
のコードを使うと、アルファベットだろうが漢字だろうが記号だろうが、一意に文字を特定できます。
世の中には様々な文字コードが存在しますし、互換性がないものもたくさんあります。
そこでLinuxのlocale定義は、UCS
のコードを使い、別途charmap
というUCS
コードから目的の文字コードに変換させるための対応リストを用意しています。
これで日本用のlocale(ja_JP)
に対して、EUC-JP
とか、Shift-JIS
とか、UTF-8
などを選択できるようになっています。
文字の文字コードとの対応
例えば日本語のひらがなの大文字の「あ」はUCS
で
U3042
となります。
これに対し、EUC-JP
では
a4 a1
UTF-8
では
e3 82 a1
となり、EUC-JP
とUTF-8
では文字コードが全然違うことがわかります。
UCS
コードからの文字コード変換の対応表は各文字コードごとに以下のディレクトリにあります。
/usr/share/i18n/charmaps
例えばEUC-JP用の対応表は以下の名前でおかれています。
EUC-JP.gz
これをエディタなどで開けてみて <U3042>
の欄を確認してみると以下のような記述になっています。
<U3042> /xa4/xa2 HIRAGANA LETTER A
xは16進数を表すプレフィックスです。
「<U3042>
はEUC-JP
ではa4a2
ってコードだよー」と定義してることがわかりますね。
一方UTF-8
は同じディレクトリに
UTF-8.gz
として置かれています。
こちらも
の欄を確認してみると以下のような記述になっています。
<U3042> /xe3/x82/xa1 HIRAGANA LETTER A
ちゃんと対応していますね。
こうしてlocaledef
を実行した場合に、これらの文字コード対応表が使われ、UCS
コードから目的の文字コードのコードに変換され、各文字コードを対応付けることができているのデス。
日付形式はどんなふうになっているの?
もうちょっと見てみましょう。日本では日付を曜日で表したりしますので、この曜日が定義されている必要がありますよね。他にも月や日は漢字ですのでこれらの使い方も定義されているはずです。
日付はLC_TIME
として定義されています。 ja_JP
のファイルではかなり下の方に定義があります(たぶん14913行あたり)。
さてこの定義にadday
といういかにも日付っぽい定義があるかと思います。そこには以下のようなコードが記述されているかと思います(;とか”とかは外しています)。
<U65E5> <U6768> <U706B> <U6C34> <U6728> <U91D1> <U571F>
これらはどんな文字に対応するのでしょうか?確認してみました。
コードの確認はwikipediaにUnicode
一覧があるのでそれを使うといいかと思います。
それぞれ表を見てみると
日 月 火 水 木 金 土
に対応しているのがわかるかと思います。
adday
の下にday
という定義もありますが、これも簡単ですね。
日曜日 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日
に対応しています。3文字でもちゃんと定義されているんですね。
他にも単位・住所の書き方・はいいいえの形式・会社組織の表記形式などなどさまざまな定義がされています。
どんな定義がされているかは、licale(5)のman
を確認してもらえたらと思います。
まとめ
最初からlocaleのオブジェクトファイルを用意していないのは、文字コードとloclaeのセットに選択の余地があるからなんだと思います。
日本語だけでも結構な数の文字コードがありますし、全部の文字コードとlocaleの組み合わせのオブジェクトファイルを用意したらかなりの分量になりそうですよね。
ですから使う分だけオブジェクトファイルを作って有効にするという方法になっているのかなと思います。