2016-09-23 8 views
1

挨拶親愛なるコミュニティ。デフォルトでのハッシュ割り当ての要素数が奇数

私はsubをハッシュとデフォルトで0になるデバッグフラグをとるperlで作ろうとしています。しかし、私はこのエラーOdd number of elements in hash assignmentを得続けます。デバッグフラグを使用しないと、動作しているようです。

ありがとうございました。

コード:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Getopt::Long; 
use POSIX qw(strftime); 


# 
#file2hash : read the file in k<file_name> e.g.=kconfig & kmem into hash table 
# 

sub file2hash { 
    my ($file) = @_; 

open(my $data, '<', $file) or die "Could not open '$file' $!\n"; 

my %HoH; 
my $key; 
my $value; 
my $who; 
my $rec; 
my $field; 

#while (my $line = <$data>) { 
while (<$data>) { 
    #print $line; 
    next unless (s/^(.*?):\s*//); #/turn off editor coloring 
    $who = $1; 
    #print $who; 
    $rec = {}; 
    $HoH{$who} = $rec; 
    for $field (split) { 
     ($key, $value) = split /=/, $field; 
     $rec->{$key} = $value; 
    } 
} 

    return %HoH; 

} 
# 
#end file2hash 
# 


# 
#print out hash table in k<file_name> format 
# 
sub hash2print{ 
    (my %HoH,my $debug) = @_; 
    #my ($debug)[email protected]_||0; 
    #my %HoH = shift; 
    #my $debug = shift || 0; 

    my $family; 
    my $role; 

    for $family (keys %HoH) { 
     #print "$family\n"; 
     for $role (keys %{ $HoH{$family} }) { 
      if ($debug){ 
       print "family:$family\n"; 
       print "role: $role\n"; 
      } 
      print "$role=$HoH{$family}{$role}"; 

     } 
     print "\n"; 
    } 
} 
# 
#end hash2print 
# 

sub dispatch{ 

     my $inc= shift; 
     my $config_f = shift || "kconfig"; 
     my $memory_f = shift || "kmem"; 

     my %h2=&file2hash($config_f); 
     my %m2=file2hash($memory_f); 

     my $today=&getDate(); 

     print "$today\n"; 
     print "$inc\n"; 
     my $inc_cnt = $m2{$today}{$inc} || -999999999; 
     print "$inc_cnt\n"; 

     #my %config = shift; 
     #my %mem = shift; 
     #my $event = shift; 
     #print $m2{$inc}{$today}; 
} 

sub getDate{ 
my $date = strftime "%m/%d/%Y", localtime; # " 
#print $date; 
return $date; 
} 

my %h2=&file2hash("kconfig"); 
my %m2=&file2hash("kmem"); 
&hash2print(%h2,1); 
&hash2print(%m2,1); 
#print &getDate(); 
#my $xcnt= &dispatch("event_c3_z2"); 
#&dispatch("event_c3_z2"); 
#print $xcnt; 

テストFILE1:

event_a1_x1: [email protected] [email protected] email1_cnt=6 
event_a1_x2: [email protected] [email protected] email1_cnt=5 
event_b2_y1: [email protected] [email protected] email1_cnt=4 
event_b2_y2: [email protected] [email protected] email1_cnt=3 
event_c3_z1: [email protected] [email protected] email1_cnt=2 
event_c3_z2: [email protected] [email protected] email1_cnt=1 

テストファイル2:

201609230012: event_a1_x1=6 
201609230744: event_a1_x2=5 
201609230844: event_b2_y1=4 
201609230342: event_b2_y2=3 
201609230245: event_c3_z1=2 
201609230100: event_c3_z2=1 
+1

投稿を編集して間違った(赤い)色を消してしまいました。これは、エディタがスラッシュなどで混乱し、そのポイントの後にすべての色が赤くなる正規表現の後によく発生します。ほとんどの場合、コメント '#/'を追加することでそれを解決しますが、コメント内で別の文字を試してみる必要があることがあります。あなたがこれが好きでない場合は、私の編集を "ロールバック"してください - 私のユーザ名の上の "編集(時間)"リンクに行き、あなたはリビジョンを見るでしょう。 – zdim

答えて

1

あなたのサブルーチンに値によって、あなたのハッシュを渡すと、この問題を作成します。 (%\に気づく)の代わりに参照することによって、あなたのハッシュ%h2を渡すようにしてください:

&hash2print(\%h2, 1); 

次に、あなたのサブhash2printに、あなたが戻って、次のようにハッシュを取得することができます:

sub hash2print { 
    (my $hashref, my $debug) = @_; 
    my %HoH = %$hashref; # dereference $hashref to get back the hash 
    ... 

あなたはあなたがそれらの背後にある概念を理解していない場合は、参考文献hereを読むことができます。

2

引数は1つのフラットリストとして関数に渡されます。一方、ハッシュには%h = qw(a b)というリストが割り当てられ、連続する要素はキーと値のペアを形成し、$h{a}'b'です。したがって、ハッシュが関数内で引数を受け取る最初の変数であれば、ハッシュはそれらのすべてを上にします。関数を返す方法については、recent postがあります。ここでは全く同じ話が適用されます。

したがって、すべてがハッシュに割り当てられ、残りのスカラーも割り当てられます。したがって、ハッシュは意図したよりも1つ多くの要素を取得し、奇数の要素で終わります。

ソリューション - このケースでは、唯一の答えのように、参照することによりハッシュを渡すInferno

sub hash2print{ 
    my ($rHoH, $debug) = @_; 
    my %HoH = %$rHoH; 
    # ... 
} 
hash2print(\%h2, 1); 

によって、彼らは非常に短くない限り参照することによってリストを渡すために、原理的には良いアイデアです。

一般的に、あなたは、ハッシュ

sub hash2print{ 
    my ($value, %HoH) = @_; 
    # ... 
} 
hash2print(1, %h2); 

スカラー最初を渡すことができますしかし、あなたの場合には$debugはオプションですので、これは行かない、と関数に最初のキーを呼び出すときに、我々はそれを残せばのハッシュは$valueになります。そのため非交渉理由がない限り

いくつかの他のコメント

  • は、グローバルを使用しないでください。小さな範囲で宣言する。

  • $rec = {};を入力する必要はありません。それはただmy $rec;と宣言できます。

  • 一般に、&を関数呼び出しの前に置かずに、ただfile2hash(...)を使用します。

+0

@ikegami非常にありがとうございました。 – zdim

関連する問題