これは本当に二重の質問です。私の2つの最終目標には、次の答えがあります。
- メカニズムの観点から、標準の文字列比較順序は何ですか?
- ドキュメントを更新できるようにするためのより良い名前は何ですか?
ソートに関するPerlのドキュメントには、ブロックなしでsort
「標準の文字列比較順序」を使用すると記載されています。しかし、その順序は何ですか?それにはもっと良い名前があるはずです。この質問では、ロケールがそれ自体の順序を定義するため、ロケールが有効になっていない状況を具体的に意味します。
過去数年間、私たちは通常、標準のソート順を「ASCIIbetically」と呼んでいました。それはLearningPerlや他の多くの本にあります。ただし、その期間は日付が付けられています。Perlは5.6以降Unicodeに対応しています。ASCIIについて話すのは昔ながらのことです。PerlもUnicodeに対応しているため、文字列を認識しています。sv.cでは、、、およびUTF-8についてPerl_sv_cmp
知っています。最初の2つは簡単です。しかし、私は3番目について自信がありません。locale
bytes
/*
=for apidoc sv_cmp
Compares the strings in two SVs. Returns -1, 0, or 1 indicating whether the
string in C<sv1> is less than, equal to, or greater than the string in
C<sv2>. Is UTF-8 and 'use bytes' aware, handles get magic, and will
coerce its args to strings if necessary. See also C<sv_cmp_locale>.
=cut
*/
PerlがUTF-8を使用してソートする場合、実際には何をソートしますか?文字列がエンコードするバイト、文字列が表す文字(おそらくマークを含む?)、または他の何か?これはsv.cの関連行(コミット7844ec1の6698行)だと思います。
pv1 = tpv = (char*)bytes_to_utf8((const U8*)pv1, &cur1);
私がその権利を読んでいる場合(私のさびたCを使用して)、pv1
オクテットに強制され、UTF-8に変換され、次に文字に強制されます(Cの意味で)。これは、UTF-8エンコーディング(つまり、UTF-8がコードポイントを表すために使用する実際のバイト)でソートしていることを意味すると思います。別の言い方をすれば、それは書記素でソートされないということです。私はこれを正しく読んでいるとほぼ確信していると思いますが、あなた方の何人かは私よりもこれについてもっとよく知っています。
それから、次の興味深い行は6708です。
const I32 retval = memcmp((const void*)pv1, (const void*)pv2, cur1 < cur2 ? cur1 : cur2);
かつては強制されていたとがpv1
、強制されているため、バイトごとに比較されているように見えます。これは、私がこれまでに読んださまざまなドキュメントに基づいてビットを比較しているように見える、で何が起こるのでしょうか?繰り返しになりますが、Unicode正規化ステップのように、bytes-> utf8->char->bytesからの移動で何が欠けているのか疑問に思っています。utf8.cでチェックアウトしても、その質問に答えることはできませんでした。pv2
char *
void *
memcmp
Perl_bytes_to_utf8
ちなみに、これはUnicode照合アルゴリズムと同じものかどうか疑問に思っていますか?もしそうなら、なぜUnicode :: Collateが存在するのですか?sort
見た目からすると、Perlが標準的な同等性を処理しているとは思いません。