散列内部哈希,无法获取数据

时间:2016-12-11 08:57:16

标签: perl

我尝试迭代包含其他哈希的哈希。

我收到错误:

  

全局符号“%arch_”需要显式包名称

这是一段代码:

my %ARCH_CODES = (
    armv7  => {id  => 102, desc => "aaaaaa"},
    i386   => {id  => 103, desc => "bbbbbb"},
    x86_64 => {id  => 104, desc => "cccccc"},
    arm64  => {id  => 105, desc => "dddddd"}
);

sub af_exit
{
    my %_error = @_;
    writeLogAndPrint($_error{'id'});
    exit($_error{'id'});
}

所以我想在armv7i386等循环中运行,然后将哈希映射发送到af_exit

for my $arch_ (keys %ARCH_CODES) {
       foo($ARCH_CODES{$arch_}); 
       # tried foo(%{ $ARCH_CODES{$arch_} } ) 
    } 

问题发生在foo方法:

sub foo
{
   my %arch = @_; # here I get an ERROR: Global symbol "%arch_" requires explicit package name
     my $res = runCommand("file zzz | grep \"$arch{id})\"");
     af_exit($ARCH_CODES{$arch});
   }
}

第二个问题是af_exit应该收到哈希所以我需要以某种方式将$ARCH_CODES{$arch}转换为哈希而不是标量

我尝试与this answer: Perl:Access values of hash inside a hash类似但得到相同的错误

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

函数foo正在获取hashref

foo( $ARCH_CODES{$arch_} );

因为%ARCH_CODES的值是哈希引用,而它需要哈希

sub foo
{
    my %arch = @_;
    # ...
}

因此,您尝试将具有单个标量(hashref)的列表分配给哈希。为此,如果您发出警告,则会收到警告Odd number of elements in hash assignment,这会直接导致您出错。

更改foo以便使用该标量

my ($rarch) = @_;

然后使用引用$rarch,或者在子my %arch = %$rarch中创建一个新哈希值,并保持函数代码的其余部分不变。

或者您可以将哈希值传递给函数foo( %{$ARCH_CODES{$arch_}} ),其余代码保持不变。一般来说,我更喜欢通过引用传递长列表和复杂数据结构。

当您使用引用($rarch)时,对它的任何更改都会更改它作为引用的数据。这允许我们有效地更改呼叫者的数据。另一方面,当您在sub中取消引用它时,您将获得本地副本。这是更安全的,因为它的意外更改(错误)不会影响调用者。

始终 use warnings;

当您调用af_exit并传递hashref

时,会重复相同的错误
af_exit($ARCH_CODES{$arch});

虽然它需要哈希

sub af_exit
{
     my %_error = @_;

以与上述相同的方式纠正它。

答案 1 :(得分:1)

以下是使用传递引用的类似方法。希望你觉得它很有用。

有几点:

  1. 在你的foreach循环和子foo中,你传递的是标量,而不是散列引用。
  2. 您还可以使用shift在子例程中接收输入,然后取消引用该变量以检索该值。
  3. 在下面的示例代码中,在子例程foo中,我执行虚拟操作以将哈希映射传递给af_exit,仅当id为102或104时,仅作为示例。

    这里我关闭了Data :: Dumper输出,我也没有打印子程序接收的引用类型的值。我们稍后会看到。

    #!/usr/bin/perl
    
    use strict ;
    use warnings  ;
    use Data::Dumper ;
    
    my %ARCH_CODES = (
        armv7  => {id  => 102, desc => "aaaaaa"},
        i386   => {id  => 103, desc => "bbbbbb"},
        x86_64 => {id  => 104, desc => "cccccc"},
        arm64  => {id  => 105, desc => "dddddd"}
    );
    
    sub af_exit
    {
            my $error = shift ;
            my $ref = ref $error ;
            #print "af_exit got variable which is of type $ref. Below is the Data Dumper output\n" ;
            #print Dumper $error ;
            print "${$error}{'id'}\n" ;
            #exit($$error{'id'});
            print "af_exit will perform exit on \[$$error{'id'}\]\n" ;
    }
    
    sub foo
    {
            my $arch = shift ;
            my $ref = ref $arch ;
            #print "af_exit got variable which is of type $ref. Below is the Data Dumper output\n" ;
            #print Dumper $arch ;
            #my $res = runCommand("file zzz | grep \"$arch{id})\"");
            if ($$arch{id} == 102 || $$arch{id} == 104)
            {
    
                    af_exit(\%$arch);
            }
    }
    
    for my $arch_ (keys %ARCH_CODES)
    {
           foo(\%{$ARCH_CODES{$arch_}}) ;
    }
    

    结果:

    %_04:04:54|root@[goat]:/home/ec2-user/cpp/study/temp> ./test
    104
    af_exit will perform exit on [104]
    102
    af_exit will perform exit on [102]
    %_04:04:56|root@[goat]:/home/ec2-user/cpp/study/temp>
    

    您始终可以使用Data :: Dumper并参考以准确显示传递的内容。再次使用Dumper和参考输出参见下面的结果。

    %_04:09:19|root@[goat]:/home/ec2-user/cpp/study/temp> ./test
    af_exit got variable which is of type HASH. Below is the Data Dumper output
    $VAR1 = {
              'desc' => 'cccccc',
              'id' => 104
            };
    af_exit got variable which is of type HASH. Below is the Data Dumper output
    $VAR1 = {
              'desc' => 'cccccc',
              'id' => 104
            };
    104
    af_exit will perform exit on [104]
    af_exit got variable which is of type HASH. Below is the Data Dumper output
    $VAR1 = {
              'desc' => 'dddddd',
              'id' => 105
            };
    af_exit got variable which is of type HASH. Below is the Data Dumper output
    $VAR1 = {
              'desc' => 'aaaaaa',
              'id' => 102
            };
    af_exit got variable which is of type HASH. Below is the Data Dumper output
    $VAR1 = {
              'desc' => 'aaaaaa',
              'id' => 102
            };
    102
    af_exit will perform exit on [102]
    af_exit got variable which is of type HASH. Below is the Data Dumper output
    $VAR1 = {
              'desc' => 'bbbbbb',
              'id' => 103
            };
    %_04:09:21|root@[goat]:/home/ec2-user/cpp/study/temp>