内容

名称

Data::Dumper - 将 Perl 数据结构转换为字符串,适合打印和 eval

概要

use Data::Dumper;

# simple procedural interface
print Dumper($foo, $bar);

# extended usage with names
print Data::Dumper->Dump([$foo, $bar], [qw(foo *ary)]);

# configuration variables
{
  local $Data::Dumper::Purity = 1;
  eval Data::Dumper->Dump([$foo, $bar], [qw(foo *ary)]);
}

# OO usage
my $d = Data::Dumper->new([$foo, $bar], [qw(foo *ary)]);
   ...
print $d->Dump;
   ...
$d->Purity(1)->Terse(1)->Deepcopy(1);
eval $d->Dump;

描述

给定一个标量或引用变量列表,以 Perl 语法输出其内容。引用也可以是对象。每个变量的内容在单个 Perl 语句中输出。正确处理自引用结构。

返回值可以 eval 以获得与原始引用结构相同的副本。(请考虑从不受信任的来源 eval 代码的安全隐患!)

任何与传递进来的引用相同的引用将被命名为$VARn(其中n 是一个数字后缀),而其他对$VARn 中子结构的重复引用将使用箭头符号进行适当的标记。如果使用Dump() 方法,您可以指定要转储的单个值的名称,或者您可以将默认的$VAR 前缀更改为其他内容。请参阅下面的 "配置变量或方法" 中的 $Data::Dumper::Varname$Data::Dumper::Terse

自引用结构的默认输出可以被eval,但对$VARn 的嵌套引用将是未定义的,因为使用一个 Perl 语句无法构建递归结构。您应该将Purity 标志设置为 1 以获取额外的语句,这些语句将正确填充这些引用。此外,如果在严格模式下被eval,您需要确保它访问的任何变量都已事先声明。

在扩展使用形式中,要转储的引用可以被赋予用户指定的名称。如果名称以* 开头,则输出将描述为哈希和数组以及代码引用提供的引用的解引用类型。如果设置了Terse 标志,则将尽可能避免输出名称。

在许多情况下,用于设置对象内部状态的方法将返回对象本身,因此方法调用可以方便地链接在一起。

有多种输出样式,所有这些样式都通过设置Indent 标志来控制。有关详细信息,请参阅下面的 "配置变量或方法"

方法

PACKAGE->new(ARRAYREF [, ARRAYREF])

返回一个新创建的Data::Dumper 对象。第一个参数是一个匿名数组,其中包含要转储的值。可选的第二个参数是一个匿名数组,其中包含值的名称。名称不需要有前导的$ 符号,并且必须由字母数字字符组成。您可以用* 开头一个名称来指定必须转储解引用类型而不是引用本身,对于 ARRAY 和 HASH 引用。

如果值的名称未定义,则将使用$Data::Dumper::Varname 指定的前缀以及一个数字后缀。

Data::Dumper 将对在转储值时遇到的所有引用进行编目。交叉引用(以 Perl 语法中的子结构名称的形式)将插入所有可能的点,保留原始值集中任何结构上的相互依赖关系。结构遍历是深度优先的,并且从第一个提供的值到最后一个值按顺序进行。

$OBJ->Dump PACKAGE->Dump(ARRAYREF [, ARRAYREF])

返回存储在对象中的值的字符串化形式(保留它们提供给new 的顺序),受以下配置选项的约束。在列表上下文中,它返回一个字符串列表,对应于提供的值。

第二种形式为了方便起见,在立即转储对象之前,简单地对它的参数调用new方法。

$OBJ->Seen([HASHREF])

查询或添加到已遇到引用的内部表中。您必须使用Reset来显式清除表(如果需要)。此类引用不会被转储;相反,它们的名称将在它们随后遇到的任何地方插入。这对于正确转储子例程引用特别有用。

期望一个匿名哈希,包含名称 => 值对。名称的规则与new中的相同。如果未提供参数,将在列表上下文中返回“已看到”的名称 => 值对列表。否则,返回对象本身。

$OBJ->Values([ARRAYREF])

查询或替换将被转储的值的内部数组。在不带参数的情况下调用时,返回一个列表形式的值。在使用对替换值数组的引用调用时,返回对象本身。在使用任何其他类型的参数调用时,将导致程序终止。

$OBJ->Names([ARRAYREF])

查询或替换将被转储的值的用户提供的名称的内部数组。在不带参数的情况下调用时,返回名称。在使用替换名称数组调用时,返回对象本身。如果替换名称的数量超过要命名的值的数量,则多余的名称将不会被使用。如果替换名称的数量少于要命名的值的数量,则替换名称列表将被耗尽,剩余的值将不会被重命名。在使用任何其他类型的参数调用时,将导致程序终止。

$OBJ->Reset

清除“已看到”引用的内部表,并返回对象本身。

函数

Dumper(LIST)

返回列表中值的字符串化形式,受以下配置选项的影响。这些值将在输出中被命名为$VARn,其中n是数字后缀。在列表上下文中将返回一个字符串列表。

配置变量或方法

使用过程式接口时,可以使用多个配置变量来控制生成的输出类型。这些变量通常在代码块中局部化,以便代码的其他部分不受更改的影响。

这些变量决定了通过调用new方法创建的对象的默认状态,但不能用于更改对象的后续状态。应使用等效的方法名称来查询或设置对象的内部状态。

当使用参数调用方法形式时,它们会返回对象本身,以便可以很好地将它们链接在一起。

导出

Dumper

示例

运行这些代码片段,快速了解该模块的行为。当您完成这些示例后,您可能希望添加或更改上面描述的各种配置变量,以查看它们的行为。(有关更多示例,请参阅 Data::Dumper 发行版中的测试套件。)

use Data::Dumper;

package Foo;
sub new {bless {'a' => 1, 'b' => sub { return "foo" }}, $_[0]};

package Fuz;                       # a weird REF-REF-SCALAR object
sub new {bless \($_ = \ 'fu\'z'), $_[0]};

package main;
$foo = Foo->new;
$fuz = Fuz->new;
$boo = [ 1, [], "abcd", \*foo,
         {1 => 'a', 023 => 'b', 0x45 => 'c'},
         \\"p\q\'r", $foo, $fuz];

########
# simple usage
########

$bar = eval(Dumper($boo));
print($@) if $@;
print Dumper($boo), Dumper($bar);  # pretty print (no array indices)

$Data::Dumper::Terse = 1;        # don't output names where feasible
$Data::Dumper::Indent = 0;       # turn off all pretty print
print Dumper($boo), "\n";

$Data::Dumper::Indent = 1;       # mild pretty print
print Dumper($boo);

$Data::Dumper::Indent = 3;       # pretty print with array indices
print Dumper($boo);

$Data::Dumper::Useqq = 1;        # print strings in double quotes
print Dumper($boo);

$Data::Dumper::Pair = " : ";     # specify hash key/value separator
print Dumper($boo);


########
# recursive structures
########

@c = ('c');
$c = \@c;
$b = {};
$a = [1, $b, $c];
$b->{a} = $a;
$b->{b} = $a->[1];
$b->{c} = $a->[2];
print Data::Dumper->Dump([$a,$b,$c], [qw(a b c)]);


$Data::Dumper::Purity = 1;         # fill in the holes for eval
print Data::Dumper->Dump([$a, $b], [qw(*a b)]); # print as @a
print Data::Dumper->Dump([$b, $a], [qw(*b a)]); # print as %b


$Data::Dumper::Deepcopy = 1;       # avoid cross-refs
print Data::Dumper->Dump([$b, $a], [qw(*b a)]);


$Data::Dumper::Purity = 0;         # avoid cross-refs
print Data::Dumper->Dump([$b, $a], [qw(*b a)]);

########
# deep structures
########

$a = "pearl";
$b = [ $a ];
$c = { 'b' => $b };
$d = [ $c ];
$e = { 'd' => $d };
$f = { 'e' => $e };
print Data::Dumper->Dump([$f], [qw(f)]);

$Data::Dumper::Maxdepth = 3;       # no deeper than 3 refs down
print Data::Dumper->Dump([$f], [qw(f)]);


########
# object-oriented usage
########

$d = Data::Dumper->new([$a,$b], [qw(a b)]);
$d->Seen({'*c' => $c});            # stash a ref without printing it
$d->Indent(3);
print $d->Dump;
$d->Reset->Purity(0);              # empty the seen cache
print join "----\n", $d->Dump;


########
# persistence
########

package Foo;
sub new { bless { state => 'awake' }, shift }
sub Freeze {
    my $s = shift;
    print STDERR "preparing to sleep\n";
    $s->{state} = 'asleep';
    return bless $s, 'Foo::ZZZ';
}

package Foo::ZZZ;
sub Thaw {
    my $s = shift;
    print STDERR "waking up\n";
    $s->{state} = 'awake';
    return bless $s, 'Foo';
}

package main;
use Data::Dumper;
$a = Foo->new;
$b = Data::Dumper->new([$a], ['c']);
$b->Freezer('Freeze');
$b->Toaster('Thaw');
$c = $b->Dump;
print $c;
$d = eval $c;
print Data::Dumper->Dump([$d], ['d']);


########
# symbol substitution (useful for recreating CODE refs)
########

sub foo { print "foo speaking\n" }
*other = \&foo;
$bar = [ \&other ];
$d = Data::Dumper->new([\&other,$bar],['*other','bar']);
$d->Seen({ '*foo' => \&foo });
print $d->Dump;


########
# sorting and filtering hash keys
########

$Data::Dumper::Sortkeys = \&my_filter;
my $foo = { map { (ord, "$_$_$_") } 'I'..'Q' };
my $bar = { %$foo };
my $baz = { reverse %$foo };
print Dumper [ $foo, $bar, $baz ];

sub my_filter {
    my ($hash) = @_;
    # return an array ref containing the hash keys to dump
    # in the order that you want them to be dumped
    return [
      # Sort the keys of %$foo in reverse numeric order
        $hash eq $foo ? (sort {$b <=> $a} keys %$hash) :
      # Only dump the odd number keys of %$bar
        $hash eq $bar ? (grep {$_ % 2} keys %$hash) :
      # Sort keys in default order for all other hashes
        (sort keys %$hash)
    ];
}

错误

由于 Perl 子例程调用语义的限制,您不能传递数组或哈希。在前面加上 \ 来传递它的引用。这将在 Perl 拥有子例程原型后得到解决。目前,您需要使用扩展用法形式,并在名称前面加上 * 以将其输出为哈希或数组。

Data::Dumper 对 CODE 引用进行了欺骗。如果在处理的结构中遇到代码引用(并且您没有设置 Deparse 标志),则会插入一个包含字符串 '"DUMMY"' 的匿名子例程,如果设置了 Purity,则会打印警告。您可以 eval 结果,但请记住,创建的匿名子例程只是一个占位符。即使使用 Deparse 标志,在某些情况下也会产生在传递给 eval 后行为不同的结果;请参阅 B::Deparse 的文档。

SCALAR 对象具有最奇怪的 bless 解决方法。

注意

不同运行的 Perl 会有不同的哈希键排序。此更改是为了提高安全性,请参阅 "perlsec 中的算法复杂度攻击"。这意味着如果数据包含哈希,则不同运行的 Perl 将具有不同的 Data::Dumper 输出。如果您需要从不同运行的 Perl 获得相同的 Data::Dumper 输出,请使用环境变量 PERL_HASH_SEED,请参阅 "perlrun 中的 PERL_HASH_SEED"。使用此方法将恢复旧的(平台特定的)排序:一个更漂亮的解决方案可能是使用 Data::Dumper 的 Sortkeys 过滤器。

作者

Gurusamy Sarathy [email protected]

版权所有 (c) 1996-2019 Gurusamy Sarathy。保留所有权利。本程序是自由软件;您可以在与 Perl 本身相同的条款下重新分发和/或修改它。

版本

版本 2.188

另请参阅

perl(1)