関数の引数のリストを文字列に正規化するにはどうすればよいですか? 2 つの引数リストが実質的に同等である場合に同じ文字列に変換されるようにするにはどうすればよいですか? アルゴリズムは
- 参照ではなく、埋め込まれたハッシュとリストを深く比較する
- ハッシュキーの順序を無視
- 3 と "3" の違いを無視する
- 比較的読みやすい文字列を生成します (必須ではありませんが、デバッグ用にあると便利です)
- 良好なパフォーマンス (Perl よりも XS を推奨)
これはmemoization、つまり引数に基づいて関数の結果をキャッシュするために必要です。
ストローマンの例として、Memoizeはこれをデフォルトのノーマライザーとして使用しますが、これは #1 と #3 に失敗します。
$argstr = join chr(28),@_;
しばらくの間、私の頼りになるノーマライザーは
JSON::XS->new->utf8->canonical
ただし、最近のスカラーの使用方法に基づいて、数値 3 と文字列 "3" の扱いが異なります。これにより、本質的に同等の引数リストに対して異なる文字列が生成され、メモ化の利点が減少する可能性があります。(大部分の関数は、3 になるか「3」になるかを知りませんし、気にもしません。)
楽しみのために、シリアライザーの束を調べて、どのシリアライザーが 3 と "3" を区別しているかを確認しました。
Data::Dump : equal - [3] vs [3]
Data::Dumper : not equal - [3] vs ['3']
FreezeThaw : equal - FrT;@1|@1|$1|3 vs FrT;@1|@1|$1|3
JSON::PP : not equal - [3] vs ["3"]
JSON::XS : not equal - [3] vs ["3"]
Storable : not equal - <unprintable>
YAML : equal - ---\n- 3\n vs ---\n- 3\n
YAML::Syck : equal - --- \n- 3\n vs --- \n- 3\n
YAML::XS : not equal - ---\n- 3\n vs ---\n- '3'\n
「等しい」と報告するもののうち、ハッシュキーの順序を無視する方法がわかりません。
引数リストを前もって調べて、すべての数値を文字列化することもできますが、これにはディープ コピーを作成する必要があり、#5 に違反します。
ありがとう!