Perl: mocking -d -f and friends. How to put them into CORE::GLOBAL

前端 未结 5 1568
遇见更好的自我
遇见更好的自我 2020-12-10 04:08

The CORE documentation has shown me how to merrily mock various built Perl functions. However, I\'m not really sure how to replace \'-d\' &c. with my methods. So this is

相关标签:
5条回答
  • 2020-12-10 04:40

    It may not be possible. The perlsub section on Overriding Built-in Functions is vague about which functions can be overridden. "Many" can, "some" can't, but aside from a handful of examples there's no definitive list.

    Normally, I'd try this:

    {
        no strict 'refs';
        *{'CORE::GLOBAL::-d'} = \&Testing::MockDir::mock_d;
    }
    

    which isn't a syntax error, but doesn't have the effect of overriding -d.

    0 讨论(0)
  • 2020-12-10 04:44

    CORE::GLOBAL doesn't work on things without prototypes. The only way I can think to do it is rewrite the opcode tree... which is not for the faint of heart. You could pull it off with a combination of B::Utils and B::Generate and a lot of experimentation.

    Simplest thing to do would be to use File::Temp to make a temporary directory structure to your liking.

    0 讨论(0)
  • 2020-12-10 05:02

    You could go the source filter route:

    package Testing::MockDir;
    use Filter::Simple;
    FILTER {   s/\s+\-d (\S+)/ Testing::MockDir::filetest 'd',$1/g };
    sub filetest {
      my ($test, $file) = @_;
      print "Mocking  -$test $file\n";
      return 1;
    }
    

    (This sample code isn't very robust. For example it won't translate -d$dir or -d "dirname with spaces", but you can beef it up until it meets the needs of your target code).

    0 讨论(0)
  • 2020-12-10 05:04

    The problem is that your app is dependent on hard-coded file specifications. You should parameterize the file specifications; then you don't have to mock anymore, you can just use Directory::Scratch or something.

    0 讨论(0)
  • 2020-12-10 05:05

    Thanks all for your answers.

    What I wound up doing is, on a per module/test target basis, I factored out the code with the "-d" into it into it's own function. Like so...

    # Because I cannot mock -d directly
    sub dirExists {
        return -d shift;
    }
    

    Then I can replace this function in the test module with like

    my $doesDirExist = 1;
    *MyModule::dirExists   = \&main::mock_dirExists;
    
    sub mock_dirExists {
        return $doesDirExist;
    }
    

    It's pretty ugly but i didn't want to get hung up on this too long and it works well enuf for my purposes

    0 讨论(0)
提交回复
热议问题