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

#!/usr/bin/perl -w use strict; use CGI qw/:standard/; print header; my @holder; open (FILE, "tempfile"); @holder=<FILE>; close FILE; my @theaters; my $name; my $link; my $info; my $rating; my $length; my $map; my $times; my $phone; my $mode; my $counter=-1; my $moviecounter=-1; my $internal=0; foreach my $line (@holder) { $internal++; if($line =~ m/<!-- LHS movie -->/) { //THIS IS THE LINE REPORTED A +S UNINITIALIZED. $mode ="LHS"; $moviecounter++; $internal=0; } elsif ($line =~ m/<!-- RHS movie -->/) { $mode = "RHS"; $moviecounter++; $internal=0; } elsif ($line =~ m/<!-- theater -->/) { $mode = "theater"; $counter++; $moviecounter=-1; $internal=0; } elsif ($mode eq "LHS") { if ($internal == 6 ) { ($link,$name)=$line=~m/<a href=\"(.*)\">(.*)<\/a>/; $theaters[$counter]{'movies'}[$moviecounter]{'name'}=$name; $theaters[$counter]{'movies'}[$moviecounter]{'link'}=$link; } elsif ( $internal == 7 ) { ($rating,$length)=$line=~m/<small>(.*)\&nbsp;\&nbsp;\&nbsp;(.*)< +\/small>/; $theaters[$counter]{'movies'}[$moviecounter]{'rating'}=$rating; $theaters[$counter]{'movies'}[$moviecounter]{'length'}=$length; } elsif ( $internal == 9 ) { ($times)=$line=~m/<Br>([^\&]*)/; $theaters[$counter]{'movies'}[$moviecounter]{'times'}=$times; } } elsif ($mode eq "RHS") { if ($internal == 4 ) { ($link,$name)=$line=~m/<a href=\"(.*)\">(.*)<\/a>/; $theaters[$counter]{'movies'}[$moviecounter]{'name'}=$name; $theaters[$counter]{'movies'}[$moviecounter]{'link'}=$link; } elsif ($internal == 5) { ($rating,$length)=$line=~m/<small>(.*)\&nbsp;\&nbsp;\&nbsp;(.*)< +\/small>/; $theaters[$counter]{'movies'}[$moviecounter]{'rating'}=$rating; $theaters[$counter]{'movies'}[$moviecounter]{'length'}=$length; } elsif ($internal == 7) { ($times)=$line=~m/<Br>([^\&]*)/; $theaters[$counter]{'movies'}[$moviecounter]{'times'}=$times; } } elsif ($mode eq "theater"){ if ($internal == 4 ) { ($link,$name)= $line=~m/<Br><A HREF=\"(.*)\"><b>(.*)<\/b><\/a>/; $theaters[$counter]{'link'}=$link; $theaters[$counter]{'name'}=$name; } elsif ($internal == 5) { ($info)=$line=~m/.*>(.*)/; $theaters[$counter]{'info'}=$info; } elsif ($internal == 6) { ($phone)=$line=~m/.*;(.*)/; $theaters[$counter]{'phone'}=$phone; } elsif ($internal == 7) { ($map)=$line=~m/<A HRef=\"(.*)\">/; $theaters[$counter]{'map'}=$map; } } }
Reports "Use of uninitialized value in string eq at ./m2.cgi line 31." ...

... any ideas?

Replies are listed 'Best First'.
(tye)Re: uninitialized weirdness
by tye (Sage) on Nov 17, 2000 at 00:08 UTC

    It turns out that $mode is what is undefined. Perl is reporting the wrong line number because it has optimized the entire if/elsif/else into a "case" (or "switch") statement.

    Update: Well, the case/switch statement bit may or may not enter into it. I recall old documentation talking about simple if/elsif/else being internally optimized into a case/switch type of flow control. What I have been able to verify is that Perl is not recording line number of the elsif lines. One easy way to see this is:

    perl -d DB<2> l 32-46 32: if($line =~ m/<!-- LHS movie -->/) { 33: $mode ="LHS"; 34: $moviecounter++; 35: $internal=0; 36 } elsif ($line =~ m/<!-- RHS movie -->/) { 37: $mode = "RHS"; 38: $moviecounter++; 39: $internal=0; 40 } elsif ($line =~ m/<!-- theater -->/) { 41: $mode = "theater"; 42: $counter++; 43: $moviecounter=-1; 44: $internal=0; 45 } elsif ($mode eq "LHS") { 46: if ($internal == 6 ) {
    and notice that the elsif lines don't have colons (":") after their line numbers. This is probably worth bringing to the attention of p5p to see if it can be fixed.

            - tye (but my friends call me "Tye")
      Says tye:
      > I recall old documentation talking about simple
      > if/elsif/else being internally optimized into a
      > case/switch type of flow control.
      Perl 4 did that, but the feature was lost in Perl 5.

      Every once in a while someone suggests adding it back to Perl 5, and what happens next is that everyone jumps in and suggests one stupid bonus feature after another. "Oh, it should do XYZ also." "Yes, and PDQ as well." After that, it sounds too complicated so nobody wants to do it.

      Damian Conway has an implementation of a switch statement based on source filters, but I think all it does is compile your code into an if-elsif internally; you don't get the optimization that you would get in C.

Re: uninitialized weirdness
by Dominus (Parson) on Nov 17, 2000 at 00:11 UTC
    Perl is reporting the wrong line numbers. Your elsif conditions are testing the value of $mode, but $mode is uninitialized. Perl is reporting the correct warning, but at the wrong place.

Re: uninitialized weirdness
by vaevictus (Pilgrim) on Nov 17, 2000 at 01:04 UTC
    The following code demonstrates and summarized my problem...
    Thanks everyone... :)
    (Mark_Dominus coded this) ->
    #!/usr/bin/perl -w $def = ''; undef $notdef; if($def eq 'foo') { # Line 4 } elsif ($def eq 'bar') { } elsif ($notdef eq "RHS") { # Line 7 }
    The error reports a problem with line4, not line 7, where the error is.
Re: uninitialized weirdness
by arturo (Vicar) on Nov 17, 2000 at 00:02 UTC

    I don't have any ideas about why it's not working at the moment (without the data the script's reading in, it's hard to tell why), but you might try populating @holder with different methods. The first one I'd suggest is not *terribly* idiomatic, but it'll make everything explicit.

    my @holder; open FILE, "tempfile" or die "Couldn't open tempfile:$!\n"; while (defined( $_ = <FILE>)) { push @holder, $_; } close FILE;
    And run the code as before.

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

      That method is my alternative... my original is a syphoning of LWP->content...
Re: uninitialized weirdness
by turnstep (Parson) on Nov 16, 2000 at 23:53 UTC

    It should work, if that is truly the line being reported. I would add a "or die..." to the open statement at the top, and see if you can shrink down the program a little bit, i.e. cut out everything else in the loop after line 31 and see if it still occurs.