Perl:嘲笑-d -f和朋友.如何将它们放入CORE :: GLOBAL

tel*_*re4 12 perl mocking

CORE文档向我展示了如何快乐地模拟各种构建的Perl函数.但是,我不确定如何替换'-d'和c.用我的方法.所以这实际上只是一个关于如何在CORE :: GLOBAL中用短划线替换函数的问题.

手动参考会很好.

package Testing::MockDir;

use strict;
use warnings;
use Exporter();
use Symbol 'qualify_to_ref';

*import = \&Exporter::import;

our @EXPORT_OK = qw(SetMockDir UnsetMockDir);

our %EXPORT_TAGS = (
    'all' => \@EXPORT_OK,
);

my %path2List = ();
my %handle2List = ();

BEGIN {
    *CORE::GLOBAL::opendir = \&Testing::MockDir::opendir;
    *CORE::GLOBAL::readdir = \&Testing::MockDir::readdir;
    *CORE::GLOBAL::closedir = \&Testing::MockDir::closedir;

    ######################### the "-" is really the problem here
    *CORE::GLOBAL::-d = \&Testing::MockDir::mock_d; # This does not work <<<<<
}

sub mock_d ($) {
    die 'It worked';
}

sub SetMockDir {
    my ($path, @files) = @_;
    $path2List{$path} = [@files];
}

sub UnsetMockDir {
    my ($path) = @_;
    delete $path2List{$path};
}

sub opendir (*$) {
    my $handle = qualify_to_ref(shift, caller);
    my ($path) = @_;
    return CORE::opendir($handle, $path) unless defined $path2List{$path};
    $handle2List{$handle} = $path2List{$path};
    return 1;
}

sub readdir (*) {
    my $handle = qualify_to_ref(shift, caller);
    return CORE::readdir($handle) unless defined $handle2List{$handle};
    return shift @{$handle2List{$handle}} unless wantarray;

    my @files = @{$handle2List{$handle}};
    $handle2List{$handle} = [];
    return @files;
}

sub closedir (*) {
    my $handle = qualify_to_ref(shift, caller);
    return CORE::closedir($handle) unless defined $handle2List{$handle};
    delete $handle2List{$handle};
    return 1;
}

1;
Run Code Online (Sandbox Code Playgroud)

Sch*_*ern 12

CORE :: GLOBAL不适用于没有原型的东西.我能想到的唯一方法是重写操作码树......这不适合胆小的人.你可以结合使用B :: UtilsB :: Generate以及大量的实验来实现它.

最简单的方法是使用File :: Temp根据自己的喜好制作临时目录结构.


Mic*_*man 7

这可能是不可能的.关于覆盖内置函数perlsub部分对于可以覆盖哪些函数含糊不清."很多"可以,"有些"不能,但除了少数几个例子之外,没有明确的清单.

通常,我试试这个:

{
    no strict 'refs';
    *{'CORE::GLOBAL::-d'} = \&Testing::MockDir::mock_d;
}
Run Code Online (Sandbox Code Playgroud)

这不是语法错误,但没有覆盖的效果-d.

  • 重写CORE :: GLOBAL必须在BEGIN时间发生,否则Perl将无法看到它.它是一个性能黑客.无论如何,CORE :: GLOBAL只适用于原型的东西.-d没有原型. (6认同)