Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

need help to fix "use of uninitialized value..."

by mlebel (Hermit)
on Feb 16, 2012 at 13:37 UTC ( [id://954229]=perlquestion: print w/replies, xml ) Need Help??

mlebel has asked for the wisdom of the Perl Monks concerning the following question:

Hello everyone,

I had a friend help me make the following code a while back and unfortunately this friend has passed away.

The original script where this code belongs inside works, but it is having unexpected behaviors. So after turning on warnings, I discovered that I am getting the following error 5 times when I run the script:

 "Use of uninitialized value within %PairsOf in concatenation (.) or string at ./test_removing_pair_unitialized_value_error.pl line 22, <DATA> line 14."

I don't know if it's the cause of the unexpected behavior in my script but I would certainly like to have this fixed.

Here is a part of my script at it's simplest form..:

#!/usr/bin/perl use strict; use warnings; my @PairLines; my %Pairs; my %PairsOf; @PairLines = <DATA>; chomp(@PairLines); foreach my $Line (@PairLines) { chomp $Line; $Line =~ s/^\s*//; $Line =~ s/\s*$//; if ($Line =~ m/^Pairing Start (.*)\s+(.*).*/) { my $Person1 = $1; my $Person2 = $2; $Pairs{$Person1} = $Person1 if (!defined($Pairs{$Person1})); $Pairs{$Person2} = $Person2 if (!defined($Pairs{$Person2})); $PairsOf{$Person1} = $PairsOf{$Person1} . " " . $Person2; $PairsOf{$Person2} = $PairsOf{$Person2} . " " . $Person1; } } __DATA__ Pairing Start Person1 Person2 Pairing End ########################################### Pairing Start Person1 Person3 Pairing End ########################################### Pairing Start Person1 Person4 Pairing End ########################################### Pairing Start Person1 Person5 Pairing End ########################################### Pairing Start Person2 Person3 Pairing End

Would anyone know a quick fix to this without re-writing the whole thing?

Thanks...

Replies are listed 'Best First'.
Re: need helpt to fix "use of uninitialized value..."
by moritz (Cardinal) on Feb 16, 2012 at 13:45 UTC

    When you run $PairsOf{$Person1}        = $PairsOf{$Person1} . " " . $Person2;, then the second occurence of $PairsOf{$Person1} isn't defined yet, which is why you get the warning.

    I'm not sure what you want to achieve, so I can't help you to fix it.

Re: need helpt to fix "use of uninitialized value..."
by DStaal (Chaplain) on Feb 16, 2012 at 14:03 UTC

    Quick fix:

    my $Person1 = defined($1) ? $1 : ''; my $Person2 = defined($2) ? $2 : '';

    But that's just covering the problem, assuming your data always has two persons in each 'Pairing Start' line. A better solution would be to re-write the regex in line 17: It's very greedy, and is probably grabbing more than you intend in several places.

    First off, drop the last '.*'. You aren't saving it, and you haven't anchored the regex on that end, so it's not doing anything except eat processor cycles. (Besides, anything it could have matched is already caught in the last capture.) Next, define exactly what is allowed in a 'Person', and refine your two captures to just capture that.

    What I suspect is happening is that some of your lines have whitespace at the end. This will then mean that the whole line ends up in $Person1, and $Person2 is empty. (Because the whitespace requirement is the only thing stopping the first capture from capturing the whole rest of the line.) I'm guessing putting (\w+) as your captures will likely do what you want, and solve your problem.

Re: need help to fix "use of uninitialized value..."
by mlebel (Hermit) on Feb 16, 2012 at 16:18 UTC

    What I am trying to achieve is a set of Pairs which is then (in the script that this code fits in) fed into another script which performs some functions on each pairs defined.

    I tried:

    my $Person1 = defined($1) ? $1 : ''; my $Person2 = defined($2) ? $2 : '';

    And the end results were the same.

    So then I tried re-writing the regex to this:

    if ($Line =~ m/^Pairing Start\s+(\w+)\s+(\w+)/) {

    And I go the same results:

    Use of uninitialized value within %PairsOf in concatenation (.) or str +ing at ./test_removing_pair_unitialized_value_error.pl line 26, <DATA +> line 14. Use of uninitialized value within %PairsOf in concatenation (.) or str +ing at ./test_removing_pair_unitialized_value_error.pl line 27, <DATA +> line 14. Use of uninitialized value within %PairsOf in concatenation (.) or str +ing at ./test_removing_pair_unitialized_value_error.pl line 27, <DATA +> line 14. Use of uninitialized value within %PairsOf in concatenation (.) or str +ing at ./test_removing_pair_unitialized_value_error.pl line 27, <DATA +> line 14. Use of uninitialized value within %PairsOf in concatenation (.) or str +ing at ./test_removing_pair_unitialized_value_error.pl line 27, <DATA +> line 14.

    I also checked the __DATA__ to ensure there were no white spaces at the end of each and every line and I wasn't able to find any..

    Any other Idea's?

      I tried: ... And the end results were the same.

      $Person1, $Person2 are not the problem

      The problem is %Pairs and %PairsOf

      $PairsOf{$Person1} is not defined (it is uninitialized), but you assign to it the value of $PairsOf{$Person1} (an uninitialized value)

      Its like writing

      my $foo = undef; my $bar = 'bar'; $foo = $foo . $bar; # UNITIALIZED!!!

      Get it?

        You are confirming what I suspected...And I understand what you are saying... The only problem is that I tried your code and it doesn't seem to give the expected result

        #!/usr/bin/perl use warnings; use strict; my $foo = undef; my $bar = 'bar'; $foo = $foo . $bar; # UNITIALIZED!!! print "foo = <$foo>\n";
        prints: foo = <bar>

        So thanks for the help though, It still help's me understand what is happening.

      In Perl >5.10, there is a new operator //=. This checks for "definedness". $Pairs{$Person1}   //= $Person1; the hash value is assigned the value of $Person1 if that hash value wasn't already defined.

      You cannot use an undefined value in a string concatenation. So, $PairsOf{$Person1} //= ""; will define $PairsOf{$Person1} to be a null string if it isn't already defined. If the value is already defined, then this should have no effect. A null string can be used in a concatenation.

      $Pairs{$Person1} //= $Person1; $Pairs{$Person2} //= $Person2; $PairsOf{$Person1} //= ""; $PairsOf{$Person2} //= ""; $PairsOf{$Person1} = $PairsOf{$Person1} . " " . $Person2; $PairsOf{$Person2} = $PairsOf{$Person2} . " " . $Person1;

        Now this fixed my problem, thank you very much!, I now have more homework to do on learning the new features of perl :)

        thanks again!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://954229]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (7)
As of 2024-04-24 20:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found