kayama kayama - 1 year ago 58
Perl Question

Odd number of elements in hash assignment with default

Greeting Dear Community.

I try to has a sub in perl that takes a hash and a debug flag which is default to zero. However I keep getting this error of Odd number of elements in hash assignment. If I don't use the debug, it seems to work.

Thanks for all the help.


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)=@_||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");
#print &getDate();
#my $xcnt= &dispatch("event_c3_z2");
#print $xcnt;

Test file1:

event_a1_x1: email1=ackee0000@gmail.com email2=kym018@gmail.com email1_cnt=6
event_a1_x2: email1=ackee0000@gmail.com email2=kym018@gmail.com email1_cnt=5
event_b2_y1: email1=ackee0000@gmail.com email2=kym018@gmail.com email1_cnt=4
event_b2_y2: email1=ackee0000@gmail.com email2=kym018@gmail.com email1_cnt=3
event_c3_z1: email1=ackee0000@gmail.com email2=kym018@gmail.com email1_cnt=2
event_c3_z2: email1=ackee0000@gmail.com email2=kym018@gmail.com email1_cnt=1

test file2:

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

Answer Source

You want to pass your hashes by value to your subroutine and this creates the problem. Try to pass your hash %h2 by reference instead (notice the \ before the %):

&hash2print(\%h2, 1);

Then in your sub hash2print, you can get the hash back in the following way:

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

You can read more about references here if you don't understand the concepts behind them.