获取Perl以打印值的完整“关键路径”(Data :: Dumper不会)

时间:2011-10-10 17:27:09

标签: perl

$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'。

3 个答案:

答案 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功能。