我有几个嵌套的数据结构,它们引用了彼此的元素。我希望能够检查这些引用,所以我正在搜索将打印嵌套结构的内存地址的东西。 Data::Dumper
的选项没问题。
以下是我的意思的一些例子:
my @a = ( [1,2,3], [4,5,6] );
print \@a;
会给你类似的东西:
ARRAY(0x20071dc8)
当您通过调试器运行相同的代码并使用x \@a
检查数组时,它将打印出来:
0 ARRAY(0x20070668)
0 ARRAY(0x2006c0d8)
0 1
1 2
2 3
1 ARRAY(0x2006c1b0)
0 4
1 5
2 6
但是使用Data::Dumper
print Dumper \@a;
看起来像这样
$VAR1 = [
[
1,
2,
3
],
[
4,
5,
6
]
];
我真正想要的是Data::Dumper
输出和调试器提供的详细信息的混合。也许这个
$VAR1 = [ ARRAY(0x20070668)
[ ARRAY(0x2006c0d8)
1,
2,
3
],
[ ARRAY(0x2006c1b0)
4,
5,
6
]
];
修改
考虑这段代码。输出并未解释$b[1]
与$a[0]
use Data::Dumper;
my @a = ( [1,2,3], [4,5,6] );
my @b = ( ["a","b","c"], $a[0] );
print Dumper \@b
print $b[1], "\n";
print $a[0], "\n";
输出
$VAR1 = [
[
'a',
'b',
'c'
],
[
1,
2,
3
]
];
ARRAY(0x2002bcc0)
ARRAY(0x2002bcc0)
此外,当一个结构引用另一个结构的内容时,这种方法是否被认为是良好的编程习惯?也许这是一个太普遍的问题,很大程度上取决于特定的代码,但我想知道你的意见。
答案 0 :(得分:4)
Data::Dumper
已经知道是否重用了引用。
在以下示例中,AoA的第2和第3个元素是相同的。这在Dumper输出中表示:
use strict;
use warnings;
my @array1 = (1..3);
my @array2 = (4..6);
my @AoA = (\@array1, \@array2, \@array2);
use Data::Dumper;
print Dumper \@AoA;
输出:
$VAR1 = [
[
1,
2,
3
],
[
4,
5,
6
],
$VAR1->[1]
];
如果要查找两个不同数据结构之间的关系,只需使用两种数据结构调用Dumper。
您可以将它们作为列表传递,或者作为另一个匿名数据结构中的值传递,如散列或数组:
use strict;
use warnings;
my @a = ([1,2,3], [4,5,6]);
my @b = (["a","b","c"], $a[0]);
use Data::Dumper;
print Dumper(\@a, \@b);
输出:
$VAR1 = [
[
1,
2,
3
],
[
4,
5,
6
]
];
$VAR2 = [
[
'a',
'b',
'c'
],
$VAR1->[0]
];
答案 1 :(得分:4)
我认为对Data::Dump
的关注太少。它由Gisle Aas编写,他是杰出的LWP
模块套件的作者。
在这种情况下,它会对你有所帮助,因为有一个伴随Data::Dump::Filtered
模块允许你提供一个回调来确切地说明每个项目应该如何在转储中显示。
此程序以您问题中的数据为例。它使用一个回调函数,在每个数组显示之前将引用的字符串化版本添加为Perl注释。转储与您的要求非常相似,作为奖励,它仍然是有效的Perl代码,必要时可以通过eval
传递。
请注意,所有转储输出都发送到STDERR
,因此我调用了select STDERR
以使print
输出与转储同步。
use strict;
use warnings;
use Data::Dump::Filtered qw/ dump_filtered /;
my @a = ( [1,2,3], [4,5,6] );
my @b = ( [ qw/ a b c / ], $a[0] );
select STDERR;
dump_filtered(\@a, \&filter);
print "\n";
dump_filtered(\@b, \&filter);
print "\n";
print '$b[1] is ', $b[1], "\n";
print '$a[0] is ', $a[0], "\n";
sub filter {
my ($thing, $ref) = @_;
return { comment => "$ref" } if $thing->is_array;
}
<强>输出强>
# ARRAY(0x45179c)
[
# ARRAY(0xa2d36c)
[1, 2, 3],
# ARRAY(0x44adc4)
[4, 5, 6],
]
# ARRAY(0x4e6964)
[
# ARRAY(0xa2d534)
["a", "b", "c"],
# ARRAY(0xa2d36c)
[1, 2, 3],
]
$b[1] is ARRAY(0xa2d36c)
$a[0] is ARRAY(0xa2d36c)