$foo{alongkeyname}{anotherlongkeyname}{yetanotherlongkeyname}{afairlyshortkeynamewellitgotlongwhileiwastypingitsoiguessnot}{bob}{something} = 1;
如何让Perl打印$ foo并向我显示完整的“路径名称” 到1?换句话说,我希望输出看起来类似于 输入上面。
Data :: Dumper不会这样做,并且长键名包裹输出, 甚至缩进形式也不那么有用。
年前,我在https://github.com/barrycarter/bcapps/blob/master/bclib.pl#L109写了我自己的“展开”子程序,输出:
<hash HASH(0x92a33a4)>
<key>
alongkeyname
</key>
<val>
<hash HASH(0x95103b4)>
<key>
anotherlongkeyname
</key>
<val>
<hash HASH(0x9510464)>
<key>
yetanotherlongkeyname
</key>
<val>
<hash HASH(0x9510434)>
<key>
afairlyshortkeynamewellitgotlongwhileiwastypingitsoiguessnot
</key>
<val>
<hash HASH(0x95bae7c)>
<key>
bob
</key>
<val>
<hash HASH(0x95cf8bc)>
something: 1
</hash HASH(0x95cf8bc)>
</val>
</hash HASH(0x95bae7c)>
</val>
</hash HASH(0x9510434)>
</val>
</hash HASH(0x9510464)>
</val>
</hash HASH(0x95103b4)>
</val>
</hash HASH(0x92a33a4)>
但这也不是很有用。
真实的项目激发了这个问题:从中获取SYNOP / BUOY数据 XML :: metaf2xml的简单哈希输出
编辑:谢谢Ben!我试过这个,它在我的例子中运作得很好。然后我在另一个哈希上尝试了它,并得到了:$VAR1 = {'remark' => [{'obsStationType' => {'stationType' => {'v' => 'AO2'},'s' => 'AO2'}},{'needMaint' => {'s' => '$'}}],'QNH' => {'inHg' => {'v' => '29.99'},'s' => 'A2999'},'visPrev' => {'distance' => {'u' => 'SM','v' => '7','rp' => '1'},'s' => '7SM'},'sfcWind' => {'wind' => {'speed' => {'u' => 'KT','v' => '3'},'dir' => {'rn' => '5','v' => '60','rp' => '4'}},'measurePeriod' => {'u' => 'MIN','v' => '2'},'s' => '06003KT'},'obsStationId' => {'id' => {'v' => 'KBTR'},'s' => 'KBTR'},'obsTime' => {'s' => '080940Z','timeAt' => {'hour' => {'v' => '09'},'minute' => {'v' => '40'},'day' => {'v' => '08'}}},'s' => 'KBTR 080940Z 06003KT 7SM SCT003 BKN200 24/23 A2999 RMK AO2 $','cloud' => [{'cloudCover' => {'v' => 'SCT'},'s' => 'SCT003','cloudBase' => {'u' => 'FT','v' => '300'}},{'cloudCover' => {'v' => 'BKN'},'s' => 'BKN200','cloudBase' => {'u' => 'FT','v' => '20000'}}],'temperature' => {'relHumid4' => {'v' => '94.15'},'dewpoint' => {'temp' => {'u' => 'C','v' => '23'}},'relHumid3' => {'v' => '94.03'},'relHumid1' => {'v' => '94.16'},'relHumid2' => {'v' => '94.17'},'air' => {'temp' => {'u' => 'C','v' => '24'}},'s' => '24/23'}};
所以我想我想回答的问题是:这个哈希的值会给我上面看到的“94.15”吗?从上面来看,这很难说清楚。
(如果有人好奇,答案是$ hash {temperature} {relHumid4} {v})
更多编辑:谢谢,伊尔玛丽。我尝试了dump_var($ VAR1)w /我上面的VAR1并得到了......
HASH(0x9ae6764) = undef;
我也尝试了dump_var({$ VAR1}),结果相同。我可能会错过一些东西。你可以剪切并粘贴上面的VAR1,看它是否有效?我在你的'使用'声明中指出了我的导出'Dumper'。
答案 0 :(得分:4)
这是一个快速自助解决方案:
use Data::Dumper 'Dumper';
sub dump_var {
my ($prefix, $var) = @_;
my @rv;
local $Data::Dumper::Indent = 0;
local $Data::Dumper::Terse = 1;
if (ref $var eq 'ARRAY' and @$var) {
for my $i (0 .. $#$var) {
push @rv, dump_var($prefix . "->[$i]", $var->[$i]);
}
} elsif (ref $var eq 'HASH' and %$var) {
foreach my $key (sort keys %$var) {
push @rv, dump_var($prefix . '->{'.Dumper($key).'}', $var->{$key});
}
} elsif (ref $var eq 'SCALAR') {
push @rv, dump_var('${' . $prefix . '}', $$var);
} else {
push @rv, "$prefix = " . Dumper($var) . ";\n";
}
return @rv;
}
和一些测试代码:
my $foo = {
alpha => [ 'beta', \ 'gamma' ],
one => { two => { three => 3, four => 3.141 },
five => { six => undef, seven => \*STDIN },
},
foobar => sub { print "Hello, world!\n"; },
};
print dump_var('$foo' => $foo);
产生输出:
$foo->{'alpha'}->[0] = 'beta';
${$foo->{'alpha'}->[1]} = 'gamma';
$foo->{'foobar'} = sub { "DUMMY" };
$foo->{'one'}->{'five'}->{'seven'} = \*::STDIN;
$foo->{'one'}->{'five'}->{'six'} = undef;
$foo->{'one'}->{'two'}->{'four'} = '3.141';
$foo->{'one'}->{'two'}->{'three'} = 3;
编辑:在测试a PHP version of this code时,我意识到它没有正确处理空数组和哈希值。我修复了代码,以便将这些值直接传递给Dumper
。
答案 1 :(得分:3)
Data :: Dumper可以通过将Indent设置为0来打印类似于您要查找的输出。
[ben@imac ~]$ perl
use Data::Dumper;
$Data::Dumper::Indent = 0;
$foo{alongkeyname}{anotherlongkeyname}{yetanotherlongkeyname}{afairlyshortkeynamewellitgotlongwhileiwastypingitsoiguessnot}{bob}{something} = 1;
print Dumper(\%foo);
输出:
$VAR1 = {'alongkeyname' => {'anotherlongkeyname' => {'yetanotherlongkeyname' => {'afairlyshortkeynamewellitgotlongwhileiwastypingitsoiguessnot' => {'bob' => {'something' => 1}}}}}};
答案 2 :(得分:0)
有关问题背后问题的可能解决方案,请参阅今天在项目新闻中公布的metaf2xml功能。