in reply to Error: Use of uninitialized value $item in concatenation (.) or string at...

For every match your are setting array index 0 in one if-clause, index 1 and 2 in another if-clause and index 3,4 and 5 in a third if-clause. Now if for example the first if-clause doesn't match, index 0 will be undef, but the other indexes will have data in it. Same for the second if-clause.

The solution depends on what your script does

if every match needs all 6 data items to be there, you have to restructure your code. If the first 'if' succeeds, any following 'if' should be inside that if and not matching should result in an error message (or in refuting that match)

If incomplete data in a match is normal you could either just use your "if defined" solution or push data onto your array instead of setting it. i.e.

#instead of $one_match_ref->[3] = $1; $one_match_ref->[4] = $2; $one_match_ref->[5] = $3; #use push( @{one_match_ref},$1,$2,$3 );

That way no holes are generated in your arrays

  • Comment on Re: Error: Use of uninitialized value $item in concatenation (.) or string at...
  • Download Code

Replies are listed 'Best First'.
Re^2: Error: Use of uninitialized value $item in concatenation (.) or string at...
by jonc (Beadle) on Jun 10, 2011 at 17:21 UTC

    Amazing! You're definitely right... I think I have to restructure, all the elements have to stay together. But the all-encompassing if-clauses won't help until I make each sent. number and it's sentence and all the grammar functions one large string...

    But if I were to use the push method, the same error persists if I don't put defined??:
    foreach my $line (@lines) { print "$line\n\n"; ##TEST ONLY## foreach my $verbform (@verbforms) { my $one_match_ref = []; #Chpt. num (Could check %seens): if ($line =~ /^Parsing file: (chpt\d+_\d+).txt/) { #$one_match_ref->[0] = $1 ; ##Only once in file push( @{$one_match_ref}, $1 ); } if ($line =~ /\b$verbform\b/i) { #Sent. num: #SentSentences: if ($line =~ /^Parsing \[(sent. \d+) len. \d+\]: \[(.+)\] +/) { #$one_match_ref->[1] = $1; ##Multiple in file #$one_match_ref->[2] = $2; #$one_match_ref->[2] =~ s/,//g; my $nocomma_sent = $2; $nocomma_sent =~ s/,//g; push( @{$one_match_ref}, $1, $nocomma_sent); } #Dependencies: if ($category_id eq "all") { if ($line =~ /subj\w*\(|obj\w*\(|prep\w*\(|xcomp\w*\(| +agent\w*\(|purpcl\w*\(|conj_and\w*\(/) { if ($line =~ /(\w+)\((\w+)\-\d+\,\s(\w+)\-\d+\)/) +{ #$one_match_ref->[3] = $1; #$one_match_ref->[4] = $2; #$one_match_ref->[5] = $3; push( @{$one_match_ref}, $1, $2, $3 ); } } } } # add the reference of match into array. push (@all_matches, $one_match_ref); } }
      if ($line =~ /^Parsing \[(sent. \d+) len. \d+\]: \[(.+)\] +/) { #$one_match_ref->[1] = $1; ##Multiple in file #$one_match_ref->[2] = $2; #$one_match_ref->[2] =~ s/,//g; my $nocomma_sent = $2; $nocomma_sent =~ s/,//g; push( @{$one_match_ref}, $1, $nocomma_sent); }

      This might be the source of one of your uninitialized values.

      See perlre for details of the match variables ($1, $2, etc.). The important thing here is that these variables are reset by the next successful match. If your substitution to remove commas finds any, then it is a successful match, after which $1 and $2 are reset to undef. Thus, if $nocomma_sent has any commas in it, when you push $1 onto your array you will be pushing undef.

      One way to avoid this is to push $1 before performing the substituion:

      if ($line =~ /^Parsing \[(sent. \d+) len. \d+\]: \[(.+)\] +/) { push( @{$one_match_ref}, $1); my $nocomma_sent = $2; $nocomma_sent =~ s/,//g; push( @{$one_match_ref}, $nocomma_sent); }

        That did the trick! Thanks a lot! (Too bad I have to restructure this method... still I won't make the same mistake!)

        By the way, don't you mean if it _doesn't_ have any commas in it?

      You might find Data::Dumper helpful. Try adding the following to the end of your script:

      use Data::Dumper; # you could put this at start of script print Dumper(\@all_matches);

      This will print your data structure in a fairly easy to understand format (see the documentation for details). It might help you to find and understand what is undefined.

        This was very helpful! I will use it to debug from now on! ...After I read all it can do. Thanks!