Perl を使用しないuse utf8
場合、文字列は 1 バイト文字のシーケンスとして解釈されます。これからわかるように、文字列には 4 バイトあります。
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10
最初の 3 バイトは文字を構成し、最後の 1 バイトは改行です。
への呼び出しは、print
これらの 4 文字を STDOUT に送信します。コンソールは、これらの文字を表示する方法を考え出します。コンソールが UTF8 を使用するように設定されている場合、これらの 3 バイトが単一の文字として解釈され、それが表示されます。
utf8
モジュールを追加すると、状況が異なります。この場合、Perl は文字列を 2 文字として解釈します。
$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10
デフォルトでは、Perl の IO レイヤーは、シングルバイト文字で動作していると想定しています。したがって、マルチバイト文字を印刷しようとすると、Perl は何かがおかしいと判断し、警告を出します。いつものように、を含めることで、このエラーの詳細な説明を得ることができますuse diagnostics
。次のように表示されます。
(S utf8) Perl はワイド文字 (>255) を想定していないときに遭遇しました。この警告は、I/O (印刷など) に対してデフォルトでオンになっています。この警告を抑える最も簡単な方法は、:utf8 レイヤーを出力に追加することです (例: binmode STDOUT, ':utf8')。警告をオフにする別の方法は、警告を追加しない 'utf8' です。しかし、それは多くの場合、不正行為に近いものです。一般に、エンコーディングでファイルハンドルを明示的にマークすることになっています。 open と perlfunc/binmode を参照してください。
他の人が指摘したように、Perl にマルチバイト出力を受け入れるように指示する必要があります。これを行うには多くの方法があります (いくつかの例については、Perl Unicode チュートリアルを参照してください)。最も簡単な方法の 1 つは、-CS
コマンド ライン フラグを使用することです。これは、3 つの標準ファイルハンドル (STDIN、STDOUT、および STDERR) に UTF8 を処理するよう指示します。
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡
対
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Unicode は大きく複雑な領域です。これまで見てきたように、多くの単純なプログラムは正しく動作しているように見えますが、その理由は間違っています。プログラムの一部を修正し始めると、すべてのプログラムを修正するまで状況が悪化することがよくあります。