perl - 如何规范化 Perl 函数参数以进行记忆化?

标签 perl

如何将函数参数列表规范化为字符串,以便两个参数列表转换为相同的字符串,如果它们实际上是等效的?该算法应

  • 深入比较嵌入式哈希和列表,而不是通过引用
  • 忽略哈希键顺序
  • 忽略 3 和“3”之间的区别
  • 生成一个相对易读的字符串(不是必需的,但对于调试来说很不错)
  • 表现良好(XS 优于 Perl)

  • 这是 memoization 所必需的。 ,即根据其参数缓存函数的结果。

    作为稻草人的例子,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。

    谢谢!

    最佳答案

    几乎任何序列化程序都会以不同的方式处理 3 和“3”,因为它不知道数字和字符串化数字对您来说是相同的,而且这种假设对于一般数据是错误的。您必须自己规范化输入或输出。

    对于输入,深度扫描将任何字符串化数字替换为其值+0 即可。如果您知道确切的数字可能在哪里输入,则可以大大缩短此扫描时间。

    对于输出,一些简单的状态机甚至正则表达式(是的,我知道输出不规则)很可能足以将纯数字字符串值剥离为数字。

    关于perl - 如何规范化 Perl 函数参数以进行记忆化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10835106/

    相关文章:

    perl - 如何为是/否用户输入创建 Tk::Dialog?

    xml - 在 Perl 中忽略 'Unclosed Token'

    c# - 帮助进行字节移位

    perl - 使用 perl 从 txt 文件中删除项目符号

    perl - 如何在 perl 中按降序对散列值进行排序?

    regex - 正则表达式在某个字符 R Perl 之前抓取单词

    regex - 如何用 Perl 中的计算表达式替换?

    perl - 未定义的子程序 &PDL::divide

    java - 如何在 Perl 中动态构建 Java 类路径?

    c - 为什么即使没有控制终端,getlogin() 也会成功