私が理解したのは、POSIXでは、ロケール定義にUTF-8などの文字エンコーディングタイプを含める必要があることです。ロケールは通常シェル環境変数として実装されます。
これら2つの概念が分離されないのはなぜですか?たとえば、サポートされているエンコーディングの数に応じて、複数のen_USロケールがあります。デザインの観点から見ると、これは汚れていて拡張するのが難しいようです。それでは、その根拠は何ですか?
ベストアンサー1
中国語などの一部の言語は、複数の文字セットで書くことができ、両方の文字セットは正確です。これには、より新しく簡素化された文字セットと、より複雑で伝統的な文字セットがあります。あるいは、モンゴル語やセルビア語をキリル文字またはラテン文字で書くこともできます。
また、ä、öなどの多くの言語のアクセント文字は、画面上で同じであっても、エンコードによってコードが異なります。したがって、äをファイルに書き込むことは、ファイルが他の標準によってエンコードされているかのように(私の例では名前がiso8859-1エンコーディングである)、ファイルに別のバイトシーケンスを書き込むことを意味します(utf8でエンコードされている場合)。
また、単一または特定の言語をサポートするエンコーディングもあります。たとえば、iso8859-1はほとんどの西ヨーロッパ言語をサポートし、iso8859-2はラテン文字で書かれるまで中央ヨーロッパと東ヨーロッパ言語をサポートします。 Asciiは英語のみをサポートしていますが、utf8は世界中のほとんどすべての言語をサポートしています。
したがって、言語と可能なエンコードの間に多対多の関係があります。言語は複数のエンコーディングでエンコードでき、ほとんどのエンコーディングは複数の言語で使用できます。
エンコーディングの互換性には多対多の関係もあります。たとえば、iso8859-2 は ascii と親互換性がありますが、ebcdic は親互換性はありません。
エンコーディングの互換性の間にも多対多の関係があります。たとえば、ebcdicはasciiに変換できますが、iso8859-2は変換できません。
その結果、部分的に互換性のある標準で構成された複雑なネットワークが存在します。使用される実際のエンコーディングは、言語と同様にロケールにも完全に属します。したがって、言語のように扱われるべきです。そのため、処理に同じ環境変数を使用します。
可能ですが、私の考えでは、他の環境変数によって処理される場合はより良いアプローチです。したがって、言語としてのエンコーディングは異なる環境変数を持ち、言語文字列の拡張ではありません。その理由は主に歴史的な理由と互換性の理由です。
しかし、少なくともglibcでは他の環境変数もサポートされています。私の英語のLinuxでは、ロケール出力は次のようになります。
$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
ご覧のとおり、さまざまなLANGおよびLANGUAGE環境変数があります。残念ながら、これはほとんどの場合、標準の互換性のためのものであり、システムが実際にはそれに従わないようです。
拡大する:
歴史について:古代では、ほとんどすべてのシステムがASCIIまたはEBCDICエンコーディングを使用するアメリカ英語でした。マルチ言語またはマルチエンコーディングのサポートは聞いたことがなく、開発された場合は回避策を使用します(たとえば、システムファームウェアの文字セットビットマップを上書きするなど)。また、私は1988年頃にc64のlatin2文字サポートを開発していました(私はlatin2にいくつかの文字しか提供していませんが、コードページは提供していませんでした。当時はコードページが何であるかさえ知りませんでした)。コードページは、もともとASCIIと同様の拡張を標準化するように設計されています。本質的に、asciiと互換性のないebcdicを使用してメインフレームの世界で同様の変換が行われました(ebcdicはもともと人間が読みやすいパンチカードを作成するために開発されましたが、asciiは簡単なデータ処理を目指しました)。
これらのエンコーディングはすべて1バイトを表すために1文字を使用します。 Linuxでは、libc4時代(90年代初頭)から多言語サポートが始まりました。 Unicodeはまだ存在しておらず、実装されていない新しい標準であり、すべてのソフトウェアは1文字= 1バイトという疑いで開発されました。 UTFを実現可能にするには、これらすべてが大幅に修正されなければならず、これは今後10年間の主要な問題の原因でした。
すべての言語拡張はバイトの上半分を使用します(asciiは7ビットのみを指定するため、ä、ö、またはキリル文字/ギリシャ語のスクリプトの場所は128から255の間です)。したがって、互いに互換性がありません。したがって、当時、言語とコードページの関係は、今の多対多のように一対一に近い。
したがって、サポートされている言語も使用するコードページを明示的に指定します。したがって、他のコードページはサポートされておらず、コードページという用語でさえ広く使用されていません。 win95がwin31のibm850からcp1251に切り替えたときにどれだけの問題が発生したかを想像することができ、ほとんどのツールはコードページの存在さえ知りませんでした。
Linuxでは、言語はLANG環境変数の2文字で決定され、それ以上ではありません。言語方言のサポート(例えば、ブラジルのポルトガル語の場合、単に「pt」ではなく「pt_BR」)は、すでにそれに対する別の拡張です。
複数のラッパーを使用して同じ言語をサポートするには、utf8が必須です。この問題は当時すでに存在していましたが(セルビア語、キリル文字、ラテン語で書くことができるものを参照)、いくつかの小さな言語でのみ問題が発生しました(私が知っている限り、セルビア語はラテン語のみを使用してすべてを書きます)。したがって、マルチエンコーディングのサポートは、継続的な開発の次のステップです。したがって、これは言語文字列の追加拡張と呼ばれる共通のパターンに従います。