eoin has asked for the wisdom of the Perl Monks concerning the following question:
Use of uninitialized value in numeric eq(==) at index.cgi line 60.error. The corresponding line numbers have been included.
Now the only thing that confuses me is that the line on which the error occurs hasn't got a numeric eq (==) on it and also the lines around it havn't got any uninitialised values on them.#57 my %pages = ("index" => '1', #58 "me" => '1', #59 "stuff" => '1', #60 "links" => '1'); #61 my $page = shift; #62 exit 0 unless $pages{$page} == '1';
|
|---|
| Replies are listed 'Best First'. | |||||
|---|---|---|---|---|---|
|
Re: Unintialised value?
by Vautrin (Hermit) on Jan 24, 2004 at 22:41 UTC | |||||
If you use strict; use warnings; whenever you try to compare an undefined value it will yelp. This is great to do, but if you want to fix that warning you should let perl know you expect the possibility of an undef value by testing for an undef value (and only performing concatanation, regular expressions, or anything else with it) if it's defined, i.e.:
You should note that you are shifting from @_ to set $page == undef; especially on this little bit of test code. So if @_ is undefined then you'll get those warnings. You can turn off warnings for uninitialized values by using:
Just be careful with the above code because:
Good luck! Vautrin | [reply] [d/l] [select] | ||||
|
Re: Unintialised value?
by neuroball (Pilgrim) on Jan 25, 2004 at 01:11 UTC | |||||
Hello, you might want to learn about the ins and outs of debugging. Most of the information can be found in the perl documentation by using perldoc perldebug. If you want to invest a bit more time and effort into debugging you might want to get a copy of Perl Debugged. Now back to your problem: You might want to print $page between line 61 and 62 and then exit (So that you actually see the result of your CGI). The only problem that I see with your script, not knowing the input, is that $page might have been set to undef and then used as hash key, which returns also undef and breakes the if-statement. Btw. The line numbers returned by errors and warnings are more of a semi-intelligent guess-timate of perl. It just gives you a point to start... but it isn't like an X on a treasure map. /oliver/
Hans: Not ze problem!
| [reply] [d/l] [select] | ||||
|
Re: Unintialised value?
by davido (Cardinal) on Jan 25, 2004 at 07:40 UTC | |||||
This will not generate the uninitialized value warning, because the right hand side equality test only gets evaluated if the left side of the logical short-circuit 'and' evaluates to truth first (if the hash key exists). If you happen to be in a situation where the key might exist but without any initialized value, you could chain a defined in there...
Not terribly elegant, but it does take into consideration all the possibilities.
Dave | [reply] [d/l] [select] | ||||
by Not_a_Number (Prior) on Jan 25, 2004 at 19:37 UTC | |||||
Is the exists test really necessary here? Shouldn't the test for defined suffice? In my (admittedly limited :-) experience, a perl variable that is defined necessarily exists, so:
should suffice. But perhaps I'm missing something, and you can show some instance where both tests are needed? TIA dave | [reply] [d/l] [select] | ||||
by davido (Cardinal) on Jan 26, 2004 at 03:03 UTC | |||||
Is the exists test really necessary here? Well, it depends. There are four things that a hash element can be (in a simple world). True, False, Undefined, or Nonexistant. I consider it at least bad style, and a bad habbit to get into, to use defined to test hash elements that may not even exist. Yes, you will not get a warning for doing so. But let's keep things clear; does a key exist or not, is it defined or not, is its value true or not? Consider the following:
So the only way to be sure whether you're looking at an undefined element, versus a nonexistant element, is to use exists. If you don't care whether it exists or not, only whether or not it's got a value, use defined, but in the example the OP gave us, he seemed to want to exit if a hash element didn't exist, and exists is the right thing for that job. I find it best to not be ambiguous about things that may bite me later.
Dave | [reply] [d/l] | ||||
|
Re: Unintialised value?
by blue_cowdawg (Monsignor) on Jan 24, 2004 at 22:06 UTC | |||||
I just tried to duplicate your problem as follows: and got a similar (or same) result. The good/bad news is that line 13 does correspond to the == operator. What value is $page set to?
| [reply] [d/l] [select] | ||||
|
Re: Unintialised value?
by Coruscate (Sexton) on Jan 25, 2004 at 05:36 UTC | |||||
Though perl will correct your "error", I'll just point out that you should be using 'eq' to compare strings, and '==' to compare numerical data. In your specific example, you won't find a difference, because perl will convert the string '1' to numerical 1 for you, but you shouldn't expect perl to think for you. :)
| [reply] [d/l] | ||||
by eoin (Monk) on Jan 25, 2004 at 16:26 UTC | |||||
Any ideas?? Eoin. | [reply] [d/l] | ||||
by Vautrin (Hermit) on Jan 25, 2004 at 22:03 UTC | |||||
Some background info: (You may or may not know this -- included for completeness) CGI is a protocol whereby executable programs can be run on a web server in a controlled enviornment which allows them access to the outside world as securely as possible. (Thus, CGI != Perl as some people think. Basically, a CGI script has to do all the work Apache or another web server would do when sending web pages. This means reading in GET variables from $ENV, and outputting the proper headers. (This is unlike a language like PHP which does all this for you unless you tell it not to)). So whenever a CGI script sends a web page to a client browser it must print the following header first: (This is a bare minimum. There are many more headers that can be sent. Download a copy of Mozilla and install LiveHTTPHeaders. This lets you watch the headers sent back and forth between the browser and server -- which is useful for learning and debugging).
Notice that the headers end with a blank new line. And these headers must be the first thing your script outputs, and they must be valid headers. And, of course, content type can change depending on whether you have an image (i.e. "image/jpeg" or "image/gif"), or XML (i.e. "application/xml" ("text/xml" is considered deprecated because it defaults to ASCII and not UTF)). Now, usually you'll write a function to do all of this for you, or you'll use CGI; in your script so that you don't have to create headers manually. But you still need to print out the headers, in the case of the CGI module it would be:
The error message in your log files is saying that no headers were printed. This should be the very first thing your script outputs If you don't print them before anything else and use valid headers you will get that error. (Hint: use CGI.pm so you don't need to learn the entire HTTP standard. It's got lots of options for headers you probably never even knew existed). Also, if Carriage Returns (^Ms) which are a staple of Microsoft files are evil in the unix world. Make sure you are saving your scripts in Unix file format. If you don't, no interpreter will be found, and you'll get errors. That may be what that second error is. | [reply] [d/l] [select] | ||||
|
Re: Unintialised value?
by Skeeve (Parson) on Jan 24, 2004 at 22:14 UTC | |||||
| [reply] | ||||
by ysth (Canon) on Jan 25, 2004 at 03:59 UTC | |||||
| [reply] | ||||