Skif Skif - 6 months ago 61
Perl Question

Add array to hash in perl

I try to add array in hash.

if ( not exists $hashtime{ $arr[0] }{ $date }{ $hour }{ $min } ) {
print "$min not exist";
$hashtime{ $arr[0] }{ $date }{ $hour }{ $min } = [ $sec ];
$create++;
};


And received the error:


Not a HASH reference at ./sort_log_by_ip.pl line 63, line 1.


Why is this code wrong?

In
perldoc perldsc
I see this construction, and I'm using something similar:

while ( <> ) {
next unless s/^(.*?):\s*//;
$HoA{$1} = [ split ];
}


Update



Code before:

if ( not exists $hashtime{ $arr[0] } ) {
$hashtime{ $arr[0] } = ( $date => { $hour => { $min => [ $sec ] } } );
$create++;
print "create for IP: $arr[0]\n";
}

if ( not exists $hashtime{ $arr[0] }{$date} ) {
$hashtime{ $arr[0] }{ $date } = ( $hour => { $min => [ $sec ] } );
$create++;
print "create for IP: $arr[0] DATE: $date\n";
}

if ( not exists $hashtime{ $arr[0] }{$date}{$hour} ) {
$hashtime{ $arr[0] }{ $date }{ $hour } = ( $min => [$sec] );
$create++;
print "create for IP: $arr[0] DATE: $date HOUR: $hour\n";
}

Answer Source

You are using a list ( ) instead of a hash reference { }, in all if blocks.

When you say

$hashtime{$arr[0]} = ( $date => { $hour => { $min => [$sec] } } );

because of LIST ( ) being evaluated in scalar context what happens is equivalent to

$hashtime{$arr[0]} = ( $date, { $hour => { $min => [$sec] } } );

ending up as

$hashtime{$arr[0]} = { $hour => { $min => [$sec] } };

since the , operator evaluates and discards operands one at a time, returning the last one.

The next if goes similarly and you then have either of (or both)

$hashtime{$arr[0]}{$date}{$min}{[$sec]}
$hashtime{$arr[0]}{$hour}{$min}{[$sec]}

However, the code that draws the error

if (not exists $hashtime{$arr[0]}{$date}{$hour})

needs a hashref at both $arr[0] and {$date}, while it clearly doesn't have both.


In both if blocks you need to assign a hash reference, obtained using { }

$hashtime{$arr[0]} = { $date => { $hour => { $min => [$sec] } } };

and

$hashtime{$arr[0]}{$date} = { $hour => { $min => [$sec] } };

as well as in the last if block.


Please indent your code properly. It is very hard to work with it the way it was posted.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download