CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
uninitialized value in hash element!!

 



jeffersno1
Novice

Mar 11, 2012, 3:58 PM

Post #1 of 9 (4998 views)
uninitialized value in hash element!! Can't Post

Hi,

I'm trying to find out why i get these errors when running the script manually.

Hi All,

I'm after some advice on a script i wrote sometime ago. I get the following errors when running the script

Use of uninitialized value in hash element at ./pstats.pl line 81, <LOGFILE> line 10742514.
Use of uninitialized value in hash element at ./pstats.pl line 84, <LOGFILE> line 10742514.
Use of uninitialized value in hash element at ./pstats.pl line 98, <LOGFILE> line 10742514.

I think its because im setting the $key = $lineArray [9], the log file where "no_sn_policy_defined" is found there are only 9 elements, 0-8.

If this is the case, is there a way i can set this element in the array before its checked?

Here is a snippet from the script

Code
foreach $line (<LOGFILE>){  
chomp($line);
if (length($line) > 0) {
@lineArray=split(",",$line);

if ( $lineArray[1] =~ /setPackId/ ) {
$key = $lineArray[9]; #### suspected error messages
if (! defined $logHash{ $key }) { #### line 81
$logHash{ $key } = [0,0,0,0,0,0];
}
my $tempa = $logHash{ $key }; ##### line 84
if ( defined $lineArray[9] && $lineArray[9] =~ /success/ ) {
@$tempa[0]++;
} elsif ( defined $lineArray[8] && $lineArray[8] =~ /no_sn_policy_defined/ ) {
@$tempa[3]++;
} elsif ( defined $lineArray[12] && $lineArray[12] =~ /conn_closed/ ) {
@$tempa[1]++;
} elsif ( defined $lineArray[12] && $lineArray[12] =~ /timedout/ ) {
@$tempa[2]++;
} elsif ( defined $lineArray[9] && $lineArray[9] =~ /no_sm_policy_defined/ ) {
@$tempa[4]++;
} elsif ( defined $lineArray[9] && $lineArray[9] =~ /no_mig_policy_defined/ ) {
@$tempa[5]++;
}
$logHash{ $key } = $tempa; #### line 98
}

foreach (sort keys %logHash)
{
$tempa = $logHash{$_};
# print "$_ : @$tempa\n";
$SetIDsuc += @$tempa[0];
$SetIDcl += @$tempa[1];
$SetIDto += @$tempa[2];
# $SetIDsn += @$tempa[3];
$SetIDnoSM += @$tempa[4];
$SetIDnoMIG += @$tempa[5];
}


log entries that script is ran against

2012-03-01_00:00:01:165,setPackId,441111111111,111.98.23.205,PMBB,undefined,2343w,1,13,success
2012-03-01_00:00:01:166,setPackId,441111111111,111.98.23.205,PMBB,undefined,2343w,1,no_sn_policy_defined,
2012-03-01_12:37:16:253,setPackId,441111111111,111.109.146.153,PMBB2011,undefined,2343a,1,13,{error,[{sm2,{error,timedout}}]}
2012-03-01_18:22:20:855,setPackId,441111111111,111.108.18.247,default,undefined,274a1,undefined,no_sm_policy_defined,
2012-03-01_17:22:44:137,setPackId,441111111111,10.214.199.95,default,undefined,274a1,undefined,no_mig_policy_defined,
2012-03-01_17:22:44:137,setPackId,441111111111,10.214.199.95,default,undefined,274a1,undefined,conn_closed,

Many thanks

Jeffers


wickedxter
User

Mar 11, 2012, 8:37 PM

Post #2 of 9 (4988 views)
Re: [jeffersno1] uninitialized value in hash element!! [In reply to] Can't Post

i tested the code and returned no errors but im sure the output isnt what you might expect. I also went threw and added scope to the script.

this retrurns:
hash keys: success & {error
values are both 0,0,0,0,0,0 or has a 1 in the area


Code
 
use strict;

my %logHash;

foreach my $line (<DATA>){
chomp($line);
if (length($line) > 0) {
my @lineArray=split(",",$line);

if ( $lineArray[1] =~ /setPackId/ ) {
my $key = $lineArray[9]; #### suspected error messages
if (! defined $logHash{ $key }) { #### line 81
$logHash{ $key } = [0,0,0,0,0,0];
}
my $tempa = $logHash{ $key }; ##### line 84
if ( defined $lineArray[9] && $lineArray[9] =~ /success/ ) {
@$tempa[0]++;
} elsif ( defined $lineArray[8] && $lineArray[8] =~ /no_sn_policy_defined/ ) {
@$tempa[3]++;
} elsif ( defined $lineArray[12] && $lineArray[12] =~ /conn_closed/ ) {
@$tempa[1]++;
} elsif ( defined $lineArray[12] && $lineArray[12] =~ /timedout/ ) {
@$tempa[2]++;
} elsif ( defined $lineArray[9] && $lineArray[9] =~ /no_sm_policy_defined/ ) {
@$tempa[4]++;
} elsif ( defined $lineArray[9] && $lineArray[9] =~ /no_mig_policy_defined/ ) {
@$tempa[5]++;
}
$logHash{ $key } = $tempa; #### line 98
}
}

}
foreach (sort keys %logHash)
{
print "$_";
my $tempa = $logHash{$_};
# print "$_ : @$tempa\n";
my $SetIDsuc += @$tempa[0];
my $SetIDcl += @$tempa[1];
my $SetIDto += @$tempa[2];
# $SetIDsn += @$tempa[3];
my $SetIDnoSM += @$tempa[4];
my $SetIDnoMIG += @$tempa[5];
}

__DATA__
2012-03-01_00:00:01:165,setPackId,441111111111,111.98.23.205,PMBB,undefined,2343w,1,13,success
2012-03-01_00:00:01:166,setPackId,441111111111,111.98.23.205,PMBB,undefined,2343w,1,no_sn_policy_defined,
2012-03-01_12:37:16:253,setPackId,441111111111,111.109.146.153,PMBB2011,undefined,2343a,1,13,{error,[{sm2,{error,timedout}}]}
2012-03-01_18:22:20:855,setPackId,441111111111,111.108.18.247,default,undefined,274a1,undefined,no_sm_policy_defined,
2012-03-01_17:22:44:137,setPackId,441111111111,10.214.199.95,default,undefined,274a1,undefined,no_mig_policy_defined,
2012-03-01_17:22:44:137,setPackId,441111111111,10.214.199.95,default,undefined,274a1,undefined,conn_closed,



naven8
Novice

Mar 11, 2012, 10:13 PM

Post #3 of 9 (4974 views)
Re: [jeffersno1] uninitialized value in hash element!! [In reply to] Can't Post

-->2012-03-01_00:00:01:166,setPackId,441111111111,111.98.23.205,PMBB,undefined,2343w,1,no_sn_policy_defined,
You are getting error because we don't have 10th element in the above line.
you might be having either space at the end or nothing after the comma.

Please add following line and try this.

Code
 
if (scalar(@lineArray) == 10 && $lineArray[9] =~ /\S/){
#do nothing here
}else {
#add 10the element here.
}



jeffersno1
Novice

Mar 19, 2012, 8:43 AM

Post #4 of 9 (4910 views)
Re: [naven8] uninitialized value in hash element!! [In reply to] Can't Post

Hi Naven,

I've tried adding the following but i still get the same result. Do i need to add the suggested code before i start the comparison?

Thanks


naven8
Novice

Mar 19, 2012, 9:04 AM

Post #5 of 9 (4908 views)
Re: [jeffersno1] uninitialized value in hash element!! [In reply to] Can't Post

You can add it after following line in your code.

Code
my @lineArray=split(",",$line);



Another way to solve your problem:

Code
push(@lineArray,"SomeKey") if(@lineArray < 9);



(This post was edited by naven8 on Mar 19, 2012, 10:02 AM)


wickedxter
User

Mar 19, 2012, 5:50 PM

Post #6 of 9 (4892 views)
Re: [jeffersno1] uninitialized value in hash element!! [In reply to] Can't Post

I tinkered with the code and tried a different approch its basic then what you had but it works as long as the log is the same and doesnt change length... it wasnt matching the {error but now works....


Code
use strict; 

my ($success, $error);

while(my $line = <DATA>){
my @liner = split(/\,/,$line);


if ($liner[9] =~ /success/){
$success++;
}elsif($liner[9] =~ /\{error/) {
$error++;
}

if($liner[8] =~ /no_sn_policy_defined|no_sm_policy_defined|no_mig_policy_defined|conn_closed/){
$error++;
#print "$liner[8]\n";
}


}

print "found $success sucessful connections\n $error faild or error happended\n";

__DATA__
2012-03-01_00:00:01:165,setPackId,441111111111,111.98.23.205,PMBB,undefined,2343w,1,13,success
2012-03-01_00:00:01:166,setPackId,441111111111,111.98.23.205,PMBB,undefined,2343w,1,no_sn_policy_defined,
2012-03-01_12:37:16:253,setPackId,441111111111,111.109.146.153,PMBB2011,undefined,2343a,1,13,{error,[{sm2,{error,timedout}}]}
2012-03-01_18:22:20:855,setPackId,441111111111,111.108.18.247,default,undefined,274a1,undefined,no_sm_policy_defined,
2012-03-01_17:22:44:137,setPackId,441111111111,10.214.199.95,default,undefined,274a1,undefined,no_mig_policy_defined,
2012-03-01_17:22:44:137,setPackId,441111111111,10.214.199.95,default,undefined,274a1,undefined,conn_closed,



(This post was edited by wickedxter on Mar 19, 2012, 6:02 PM)


BillKSmith
Veteran

Mar 20, 2012, 11:55 AM

Post #7 of 9 (4859 views)
Re: [jeffersno1] uninitialized value in hash element!! [In reply to] Can't Post

All of your sample data contains a final comma. This is probably intended to create an extra field. It does work if there is any whitespace between that comma and the newline.

If you change your 'for' loop to a 'while' loop (as wickedxter did), the error messages will tell you the offending line numbers in the data file. Adding a space to end of each of these lines should solve your original problem.

It is also possible to solve the problem the way you were thinking. Create a new array element if one does not exist.


Code
@lineArray=split(",",$line);  

$lineArray[9] ||= 'foo';




Even if one of these works, I still recommend a major rewrite along the lines wickedxter tried. The existing code will be very hard to maintain.
Good Luck,
Bill


jeffersno1
Novice

Mar 20, 2012, 1:34 PM

Post #8 of 9 (4855 views)
Re: [BillKSmith] uninitialized value in hash element!! [In reply to] Can't Post

Thanks BillKSmith for the reply

Thats just what i needed, i've been thinking i need to rewrite this script, but couldnt bring myself to do it.

My issue is: what the best practice? I understand the fundermentals but im not sure what approach to take, the current script takes 230 seconds to run against 10,421,989 lines in 1 log file which is 915M in size

To give you an idea of the script im basically running the same piece of code 6 times all within elseif statements, just changeing the if statement to match different strings, then foreach hash the total and unique counts are printed.

Any suggestions going forward are much apprecited,

Many thanks

Jeffers


BillKSmith
Veteran

Mar 21, 2012, 7:00 AM

Post #9 of 9 (4827 views)
Re: [jeffersno1] uninitialized value in hash element!! [In reply to] Can't Post

The objective of good practice is to write code that is easy to understand and modify. If the resulting code is too slow (or too big), use profile to identify the offending parts. Rewrite only those parts, documenting what good practices you compromised and why. Use benchmark to measure the improvement. The cost of modifying software usually far exceeds to cost of the initial development. (I have made changes to a FORTRAN program that had been modified many times over 30 years.) Make it easy for the next guy, it may be you!

I strongly recommend the book "Perl Best Practices". (Be sure to read the Preface).

Sorry I do not have time for more specific recommendations now, maybe later.
Good Luck,
Bill

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives