2

我正在使用 Data::Dumper 和 Data::Dumper::Simple(DD 和 DDS)以脚本的详细模式打印哈希,我希望能够与可能没有安装这些模块的其他人共享它,所以我正在检查它们是否已加载。

在不检查模块是否成功加载的情况下,我将如何加载和使用它们的 MWE 是:

use strict;
use warnings;

use Data::Dumper;
use Data::Dumper::Simple;
$Data::Dumper::Sortkeys = 1;

my %testHash=();

warn Dumper(\%testHash);

哪个打印:

$testHash = {};

使用此处描述的方法首先检查模块是否已加载,如果是,则仅使用 Dumper 方法,我将代码重写为:

use strict;
use warnings;


my $dumperLoaded = 1;
my $rc;

$rc = eval
{
    require Data::Dumper;
    Data::Dumper->import();
    1;
};
if(!$rc)
{
    print "Data::Dumper not found\n";
    $dumperLoaded = 0;
}

$rc = eval
{
    require Data::Dumper::Simple;
    Data::Dumper::Simple->import();
    1;
};
if(!$rc)
{
    print "Data::Dumper::Simple not found\n";
    $dumperLoaded = 0;
}
if($dumperLoaded){
    $Data::Dumper::Sortkeys = 1;
}

my %testHash=();

if($dumperLoaded){
    warn Dumper(\%testHash);
}

我的输出现在是:

Name "Data::Dumper::Sortkeys" used only once: possible typo at temp.pl line 51.
$VAR1 = {};

现在散列转储不显示变量名称testHash,好像 DDS 没有加载。但是,我的脚本并没有抱怨它无法加载 DDS。我可以通过注释掉来在我的第一个 MWE 中复制它use Data::Dumper::Simple;

我的问题:为什么我的脚本的第二个版本,检查模块加载,只打印 DD,而不是加载 DDS?

额外的问题:在这样的条件模块加载场景中设置 SortKeys 的正确方法是什么?

谢谢。

4

2 回答 2

5

Data::Dumper::Simple是一个源过滤器。源过滤器必须在 Perl 的编译阶段加载,否则它们将无法处理脚本中的任何源代码。

可能有效(未经测试)有效:

my $dumperLoaded;
BEGIN { 
    $dumperLoaded = eval "use Data::Dumper::Simple;1" ||
                    eval "use Data::Dumper;1";
}
于 2017-10-24T13:34:53.847 回答
1

好的,首先 - 测试返回代码很好,但实际上你可能更好地$@用于检查 eval 是否有效。

例如:

eval { 
   require Data::Dumper;
   Data::Dumper -> import();
};
if ( $@ ) { 
   print "loading failed, error was: $@\n";
} 

但你的问题的根源是这样的:

唯一导出的是 Dumper() 函数。

好吧,实际上这不是真的。什么都没有导出。但是,源过滤器用于自动重写对 C 的任何明显调用,以便它只做正确的事情。

因为当您通过 require/import加载时不会发生这种情况,因此不会发生函数的重载。Data::Dumper::SimpleDumper

看着它-我实际上看不到一种简单的方法来称呼“备用翻斗车”

于 2017-10-24T13:38:37.883 回答