無題の備忘録

IT技術について調べたことや学んだこと、試したこと記録するブログです。Erlang、ネットワーク、 セキュリティ、Linux関係のものが多いです。

Erlang の string モジュールを一通り試す - 準備

OTP 20.0 で string モジュールに多くの関数が追加されていたのに、最近気がついた。一通り試そうと思う。

その前に、string モジュールの基本をおさらいする。すべて、公式ドキュメントに記載されている内容だ。

string モジュールは、文字列処理用の関数を提供するモジュールである。

このモジュールにおける string とは、unicode:chardata() 型で表される、UTF-8 エンコードのコードポイントのリスト、UTF-8 エンコードのコードポイントのバイナリ、もしくはこの2つが組み合わせのことだ。

"abcd"               は有効な string である
<<"abcd">>           は有効な string である
["abcd"]             は有効な string である
<<"abc..åäö"/utf8>>  は有効な string である
<<"abc..åäö">>       は有効な string でないが、Latin-1 エンコードのコードポイントのバイナリだ。
[<<"abc">>, "..åäö"] は有効な string である
[atom]               は有効な string ではない

このモジュールは、書記素クラスタで動作する。書記素クラスタは、ユーザが認識する自然な1文字はいくかのコードポイントによって表すことができる。

$ erl +pc unicode
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V9.2  (abort with ^G)
1> [229].
"å"
2> [97,778].
"å"
3> [101, 778].
"e̊"

"ß↑e̊" の文字列の長さは、コードポイントでは[223,8593,101,778]UTF-8バイナリでは<<195,159,226,134,145,101,204,138>>と表されるが、3である。

ただし、class prepend (?)および非モダンハングルのコードポイントの書記素クラスタは、パフォーマンス上の理由で find/3replace/3split/2split/2、およびtrim/3 では処理されないとのことだ。class prepend というのが具体的に何を指すのかは良くわからなかった。

文字列の分割と追加は、書記素クラスタの境界で行われる。文字列を追加した結果が有効か、または正規化されているかの検証はされない。

ほとんどの関数は、すべての入力が1つの形式に正規化されることを想定している。正規化には例えば、unicode:characters_to_nfc_list/1 を使う。

入力の言語またはロケール固有の処理は、どの関数でも考慮されない。

関数は、無効な入力文字列に対してクラッシュする可能性がある。 たとえば、関数はUTF-8バイナリを想定していますが、すべての関数がすべてのバイナリが正しくエンコードされていることを検証するわけではない。

特に指定がない限り、戻り値の型は入力型と同じ。つまり、バイナリ入力はバイナリ出力を返し、リスト入力はリスト出力を返し、混合入力は混合出力を返す。

このモジュールは、Erlang / OTP 20で作り直され、unicode:chardata() を処理し、書記素クラスタで動作する。 入力としてLatin-1リストでのみ機能する古い関数は引き続き使用できるが、将来のリリースでは非推奨になるので、使用しない。

主なData Typesについて

direction() = leading | trailing
grapheme_cluster() = char() | [char()]

leading は先頭、trailing は末尾のこと。 grapheme_cluster() は、1つ以上のコードポイントから構成されるユーザが認識する1文字のこと。

ちなみに、Erlangシェル上でUnicodeの文字列はコードポイントのリストとして表示される。

$ erl
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V9.2  (abort with ^G)
1> "あいうえお".
[12354,12356,12358,12360,12362]

[12354,12356,12358,12360,12362]の各要素が あ、い、う、え、お のコードポイントだ。

人が読める文字として表示したい場合は、+pc unicodeフラグを使う。

$ erl +pc unicode
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V9.2  (abort with ^G)
1> "あいうえお".
"あいうえお"

では、次回から、実際に試していきたい。