1

我正在从YAML文件中读取一些信息

groceries.yaml

# comment
fruit:
   apples: 1
   oranges: 1
   grapes: 1
vegetables:
   potatoes: 1
   onions: 1
   leeks: 1

perl脚本

myscript.pl

#!/usr/bin/perl

use strict;
use warnings;
use YAML::Tiny;

# Create a YAML file
my $stuff = YAML::Tiny->new;

# Open the config
$stuff = YAML::Tiny->read( 'groceries.yaml' );

print "Fruit: ", %{($stuff->[0]->{fruit})},"\n";
print "Vegetables: ", %{($stuff->[0]->{vegetables})},"\n";

exit

这很好用,但我想有一个哈希值fruit和一个vegetables. 我天真的尝试是

my @keys = keys %{($stuff->[0])};
foreach my $key (@keys){
        my %{ $key }  = %{($stuff->[0]->{$key})},"\n";
}

但显然这不起作用。

我很想了解我做错了什么,并对实现相同想法的不同工作流程持开放态度:)

4

3 回答 3

2

试试这个 :

#!/usr/bin/perl

use strict;
use warnings;
use YAML::Tiny;
use Data::Dumper;

# Create a YAML file
my $stuff = YAML::Tiny->new;

# Open the config
$stuff = YAML::Tiny->read( 'groceries.yaml' ); 

my %fruits = %{ $stuff->[0]->{fruit} };
my %vegetables = %{ $stuff->[0]->{vegetables} };

我不知道你为什么在代码中加上括号:

%{($stuff->[0]->{$key})},"\n";

我认为这是问题所在。


要遍历 HASH,

use Data::Dumper;
# ...
foreach my $key (keys %{ $stuff->[0] }) {
    print Dumper $stuff->[0]->{$key};
}

编辑2

#!/usr/bin/perl

use strict;
use warnings;
use YAML::Tiny;
use Data::Dumper;

# Create a YAML file
my $stuff = YAML::Tiny->new;

# Open the config
$stuff = YAML::Tiny->read( 'groceries.yaml' );

my %top_h;

foreach my $key (keys %{ $stuff->[0] }) {
    $top_h{$key} = $stuff->[0]->{$key};
}

print Dumper \%top_h;
于 2013-03-22T00:03:22.363 回答
2

此解决方案使您能够访问%fruit%vegetables. 它们被声明为包全局变量 usingour以便它们将在符号表中,然后允许您使用符号引用或 glob 分配。您还需要关闭strict refs才能启用此功能。另请参阅此参考

use strict;
use warnings;
use YAML::Tiny;
use Data::Dumper;

my $stuff = YAML::Tiny->read('groceries.yml');

my %groceries = %{$stuff->[0]};

our %fruit;
our %vegetables;
{
    no strict 'refs'; 
    #no strict 'vars'; # don't need above 'our' declarations with this
    while (my ($key, $val) = each %groceries) {
        %$key = %$val;
        # or *$key = $val;
    }
}

print Dumper \%fruit;

如果您事先不知道密钥,那么您还需要关闭,strict vars这样您就不需要在分配给它们之前声明哈希。但是,当您直接使用哈希时,您可能会收到警告。

但是说了这么多,我认为使用%groceries.

于 2013-03-22T06:57:33.697 回答
1
my ( $fruit, $vegetables) = @{$stuff->[0]}{ qw<fruit vegetables> };

如果您想循环执行此操作,首先,我会将第一个“文档”保存到本地参考。

my $yaml = $stuff->[0];

然后在一个while循环中,执行以下操作:

while ( my ( $k, $v ) = each %$yaml ) {
    say ucfirst( $k ) . ': ' . %$v;
}

您也可以使用List::Pairwise并执行此操作:

mapp { say ucfirst( $a ) . ': ' . %$b } %{ $stuff->[0] };
于 2013-03-22T00:04:32.157 回答