代码之家  ›  专栏  ›  技术社区  ›  Robert

如何模拟Perl的unlink函数?

  •  1
  • Robert  · 技术社区  · 1 年前

    我想模仿Perl unlink 以测试我的代码是否删除了正确的文件。基于 this question and its answers this other question and its answers ,我尝试过:

    use strict;
    use warnings;
    use subs 'unlink';
      
    sub mock_unlink {
        use Data::Printer; p @_;
        return;
    }     
    
    BEGIN {
        no warnings qw/redefine/;
        *CORE::GLOBAL::unlink = \mock_unlink;
        # *unlink = \mock_unlink;
        use warnings;
    }
              
    unlink "some file";
    

    但当我运行这个时,我的模拟函数确实被调用了,但参数列表是空的。我也得到了警告 取消链接 未定义。

    $ perl mcve.pl
    []
    Undefined subroutine &main::unlink called at mcve.pl line 17.
    

    我希望它能打印出来

    ["some file"]
    

    我试过留言 *unlink = \mock_unlink; 相反,但这并没有改变任何事情。

    我需要如何嘲笑 取消链接 检查我的代码试图删除哪些文件?

    1 回复  |  直到 1 年前
        1
  •  1
  •   zdim    1 年前
    use strict;
    use warnings;
    use feature 'say';
    
    #use subs 'unlink';
    use subs 'mock_unlink';  # but do you really need it?
    
    sub mock_unlink {
        say "Unlink: @_";
        return;
    }
    
    BEGIN {
        no warnings qw/redefine/;
        *CORE::GLOBAL::unlink = \&mock_unlink;
        #use warnings;  # no need, `no warnings` is scoped to this block
    }
    
    unlink "some file";
    

    笔记

    • 需要 \&subname 为了 get a reference 指定的子(不是 \subname )

    • 这个 use subs pragma预先声明命名的subs,以便可以使用它们 甚至在定义之前都没有括号。 你真的需要吗?

      为什么它不起作用 use subs unlink; ? ... 不知道。显然,预先声明要替换的子会打乱流程。我发现后会更新

    • 这个 use warnings / no warnings 是词法的——一旦退出作用域,效果就会过期。因此,您不需要显式地重新启用警告(但这也不是错误)。

    • 这个 return; 在子回报中 undef 。这通常表示某种故障 unlink 如果删除失败,则返回。因此,在这里,它表明确实没有任何内容被删除,这似乎是合理的。忽略它将返回最后一个有返回的语句的返回值,在本例中为 say 如果成功,就会回报成功。这对我来说也很合理 测试。