2016-12-11 3 views
0

私は他のハッシュを含むハッシュを反復しようとします。ハッシュ内のハッシュは、データをフェッチできません。

私はエラーを取得する:ここで

Global symbol "%arch_" requires explicit package name

はコードです:

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'}); 
} 

だから私は、armv7にループ内で実行さi386などと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に似て作ってみましたが、同じエラーを取得

任意のアイデア?それはあなたが単一のスカラーとリストを割り当てるしようとしているハッシュ

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

を期待しながら、%ARCH_CODESの値は、ハッシュ参照であるため、

+0

'$ ARCH_CODES {$のarch_は}'値=> '{ID => 102、DESC => "AAAAAA" を} 'が含まれたハッシュ・リファレンスであり、あなたが'私の$アーチを使用することができます= @_ 'ハッシュリファレンスを取得し、' foreach my $ keys(keys%$ arch) 'のようにアクセスしてください。 – AbhiNickz

+0

@AbhiNickzしかし、この場合は' af_exit($ ARCH_CODES {$ arch});を使用できません; – snaggs

+0

'af_exit($ arch);'を使って 'hash'参照をサブに送り、' my $ _error = @_; 'のように再利用することができます – AbhiNickz

答えて

2

機能fooはハッシュリファレンス

foo($ARCH_CODES{$arch_}); 

を得ています(hashref)をハッシュに変換します。このため、警告が表示された場合はOdd number of elements in hash assignmentという警告が表示されます。これは直接エラーにつながります。

変更fooので、それはその後

my ($rarch) = @_; 

スカラーのいずれかの参照$rarchを使用、またはサブ、my %arch = %$rarchで新しいハッシュを作り、そのまま関数のコードの残りの部分を維持することを要すること。

または、関数にハッシュを渡すことができます。foo(%{$ARCH_CODES{$arch_}})と残りのコードはそのままです。一般的に、長いリストと複雑なデータ構造を参照することが望ましいです。

リファレンス($rarch)を使用して作業している場合は、その変更が参照のデータを変更します。これにより、発信者のデータを効率的に変更することができます。一方、あなたがサブリファレンスでそれを参照解除すると、ローカルコピーが得られます。これは、偶発的な変更(エラー)が呼び出し側に影響を与えないため、より安全です。

ください常にuse warnings;


あなたはそれが

sub af_exit 
{ 
    my %_error = @_; 

正しいハッシュに期待していながら、それをハッシュリファレンス

af_exit($ARCH_CODES{$arch}); 

を渡し、af_exitを呼び出したときに同じエラーが繰り返されますそれは同じw上記のように。

+0

@snaggs私は答えを編集しました(他の2つの方法を追加しました)、もっと役に立つかどうか教えてください。 – zdim

1

これは、参照渡しを使用した同様の方法です。あなたはそれが有用であることを願っています。

ポイントのカップル:あなたのforeachループとサブのfooで

  1. 、あなたはスカラーではなく、ハッシュリファレンスを渡しています。
  2. また、シフトを使用してサブルーチンで入力を受け取り、変数を参照解除して値を取得することもできます。

以下のサンプルコードでは、サブルーチンfooで、idが102または104の場合にのみ、ハッシュマップをaf_exitに渡すためのダミー操作を例として示しています。

ここでは、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|[email protected][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|[email protected][goat]:/home/ec2-user/cpp/study/temp> 

あなたはいつも周りに渡されている正確に何を表示するには、Data :: Dumperのとrefを使用することができます。 Dumperとリファレンス出力をオンにして、下のResultを再度参照してください。

%_04:09:19|[email protected][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|[email protected][goat]:/home/ec2-user/cpp/study/temp> 
関連する問題