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

I am a perl newbie, but I inherited a very large perl program, and am learning a lot from it. I added the line:

use strict;

to take advantage of the additional warnings and errors I get from it. But, now at run time, I am seeing this message (among others)

Use of uninitialized value in pattern match (m//) at secalert_index_verbose.cgi line 180.
.

Now this is the code before and after line 180:

($ENV{HTTP_USER_AGENT} =~ /MSIE/)
&& do {
  # Internet Explorer
  $style{'body','font-size'}='10pt';
  $style{'th','font-size'}='8pt';
  $style{'td','font-size'}='6pt';
  $style{'pre','font-size'}='10pt';
  $titlebox_size='4';
  1;
} || do {
  # Netscape
  $style{'body','font-size'}='10pt';
  $style{'th','font-size'}='10pt';
  $style{'td','font-size'}='8pt';
  $style{'pre','font-size'}='10pt';
  $titlebox_size='5';
};

Line 180 is actually the line that reads:

} || do {

What's it talking about, and how do I fix it? I can't find the string 'm//' anywhere in my code.

Replies are listed 'Best First'.
Re: Unknown warnings/errors
by Tanktalus (Canon) on Jan 29, 2007 at 20:50 UTC

    The way many compilers (including perl, it seems) handle multi-line statements is to treat the entire line either as the first or last line in the group (here, the last). You have a single statement spread over a bunch of lines, it's no wonder it gets confusing. The error is thus pointing to the first line there, since /MSIE/ is short for m/MSIE/ (see perlop).

    There are many improvements that should be made here, the least of which is to use proper if-then-else processing, and checking your values appropriately:

    if (exists $ENV{HTTP_USER_AGENT} and $ENV{HTTP_USER_AGENT} =~ /MSIE/) { # handle MSIE case } else { # handle "other" case (could be Netscape, Firefox, Konqueror, Opera, + Nautilus, ...) }
    More major is to start using CGI instead of checking the environment, and to acknowledge more browsers are out there than you can shake a stick at, so just follow the standards and stop second-guessing the user.

Re: Unknown warnings/errors
by Joost (Canon) on Jan 29, 2007 at 20:51 UTC

      That makes sense. I'm usually running this from a web browser where it is set, but I'm running this in a test mode from a unix command line. Thank you.

        FYI, you can test ENV variables from the command line like so:

        $ HTTP_USER_AGENT=MSIE perl myscript.cgi

        Or:

        $ HTTP_USER_AGENT=FireFox perl myscript.cgi

        That is, put the environment variable name plus what value you want it to have, separated by an equals sign, immediately preceding your invocation of the script. Just a handy way to test things like that out.

        But I'll second Joost's advice (though not to the letter) and suggest dealing with goofy IE CSS implementations through plain CSS.



        --chargrill
        s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)
Re: Unknown warnings/errors
by blazar (Canon) on Jan 30, 2007 at 11:05 UTC
    ($ENV{HTTP_USER_AGENT} =~ /MSIE/) && do { # Internet Explorer $style{'body','font-size'}='10pt'; $style{'th','font-size'}='8pt'; $style{'td','font-size'}='6pt'; $style{'pre','font-size'}='10pt'; $titlebox_size='4'; 1; } || do { # Netscape $style{'body','font-size'}='10pt'; $style{'th','font-size'}='10pt'; $style{'td','font-size'}='8pt'; $style{'pre','font-size'}='10pt'; $titlebox_size='5'; };

    On an unrelated basis to your actual problem, I do like to use short circuiting logical operators for flow control. But then the rule of a thumb is to use low precedence ones for this, and high precedence ones to operate on values (of course it actually doesn't make a difference here). However in this particular case they won't buy you anything over a regular, proper, if... else. Just so to let you know. Incidentally if you do so you won't incur in the "misplaced" warning line you're incurring into now.

Re: Unknown warnings/errors
by Anonymous Monk on Jan 30, 2007 at 10:26 UTC
    If you use diagnostics, you'll get more
    use diagnostics; use warnings; ($ENV{HTTP_USER_AGENT} =~ /MSIE/) && do { warn 1}; __END__ Use of uninitialized value in pattern match (m//) at - line 4 (#1) (W uninitialized) An undefined value was used as if it were alread +y defined. It was interpreted as a "" or a 0, but maybe it was a mi +stake. To suppress this warning assign a defined value to your variables. To help you figure out what was undefined, perl tells you what ope +ration you used the undefined value in. Note, however, that perl optimiz +es your program and the operation displayed in the warning may not necessa +rily appear literally in your program. For example, "that $foo" is usually optimized into "that " . $foo, and the warning will refer +to the concatenation (.) operator, even though there is no . in your program.