如何规范化函数参数列表到一个字符串,以便两个参数列表转换为相同的字符串iff它们实际上是等效的?该算法应该如何正常化记忆的Perl函数参数?
- 比较嵌入散列和列表深,而不是通过引用
- 忽略散列键顺序
- 忽略3和“3”
- 产生相对可读的字符串之间差(不是必需的,但好到有调试)
这是必要的表现良好(XS优于的Perl),即基于其参数缓存函数的结果。
作为一个稻草人例如,Memoize使用此作为默认正规化,从而未能#1和#3:
$argstr = join chr(28),@_;
有一段时间我去到正规化是
JSON::XS->new->utf8->canonical
然而,根据最近使用的标量的方式来处理数字3和字符串“3”differently。这可以为基本上等价的参数列表生成不同的字符串,并降低记忆收益。 (绝大多数的功能将不知道或不关心,如果他们得到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。
谢谢!
还有[Test :: More](http://metacpan.org/module/Test::More)的is_deeply,和[Test :: Deep](http://metacpan.org/module/Test :: Deep)的eq_deeply。 – Ether