2016-09-23 43 views
1

致敬亲爱的社区。默认散列分配中元素的奇数

我试图在perl中制作一个sub,它需要一个散列和一个默认为零的调试标志。但是我不断收到这个错误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; 

测试文件1:

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

参数作为一个扁平列表传递给一个函数。另一方面,散列可以被分配列表%h = qw(a b),其中连续的元素形成键值对,$h{a}'b'。所以当一个散列函数是第一个在函数中接收参数的变量时,它将它们全部挖掘出来。关于函数如何返回这里是recent post,其中应用完全相同的故事。

所以一切都被分配给散列,剩下的标量也是如此。因此哈希获得比预期更多的元素,并以奇数个元素结束。

一个解决方案 - 在这种情况下,只有通过引用由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