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

Dear Monks- I am going crazy trying to figure out what i'm doing wrong (and i'm sure it's something that'll be obvious). I'm getting the "Use of uninitialized value in concatenation (.) or string at ... line 33." message, but it seems to me that everything must be initialized? what am i missing?

(i'm just using line 33 as a debugging line - it's really part of an SQL statment, but since i keep getting this error, although with a prior edit, it wasn't happening, and i'm not sure what i might have inadvertantly added or deleted

2 use strict; 3 use CGI qw/:standard :html3 :netscape/; 4 use Win32::ODBC; 5 use POSIX qw(strftime); 6 7 my $q = new CGI; 8 my ($mdy, $nomname, $nomemail, $nominst, $submitname, $submitemail, +$submitcat, $submitinst, $submitdiv, $mentor, $ptcare, $clinres, $com +ments); 9 10 my %in = map { $_ => $q->param($_) } $q->param; 11 for (keys %in) { 12 $in{$_} =~ s/'/''/g; 13 print "$_ = $in{$_}</p>"; 14 } 15 16 $mdy = strftime "%m/%d/%Y %H:%M:%S",localtime; 17 $nomname = $in{NOMNAME}; 18 $nomemail = $in{NOMEMAIL}; 19 $nominst = $in{NOMINST}; 20 $submitname = $in{SUBMITNAME}; 21 $submitemail = $in{SUBMITEMAIL}; 22 $submitcat = $in{SUBMITCAT}; 23 $submitinst = $in{SUBMITINST}; 24 $submitdiv = $in{SUBMITDIV}; 25 $mentor = $in{MENTOR}; 26 $ptcare = $in{PTCARE}; 27 $clinres = $in{CLINRES}; 28 $comments = $in{COMMENTS}; . . 33 print "('$mdy','$nomname','$nomemail','$nominst','$submitname','$su +bmitemail', '$submitcat','$submitinst','$submitdiv','$mentor','$ptcar +e','$clinres', '$comments')";
TIA for pointing out where i'm being stupid (and any other pointers would be greatly appreciated - i'm a part-time/hobbyist perl programmer - wish i had more time to learn perl properly!!).

Replies are listed 'Best First'.
Re: help with strict
by Ovid (Cardinal) on Jun 03, 2004 at 22:55 UTC

    Since you are assinging variables from a hash, it's difficult to tell if you've misspelled the keys. One way to find out is to print the names of the params and visually compare each one to your hash keys. (Since you're already printing them out, you should have no problem with that.)

    Another method is to keep breaking your print line in two to perform a binary search for the variable giving you the uninitialized warning.

    Yet another idea would be to use the hash directly rather than the variables. I'm not sure why you're copying the data to new variables since you are not untainting anything (though I realize this could be a simplified example.)

    Cheers,
    Ovid

    New address of my CGI Course.

Re: help with strict
by davidj (Priest) on Jun 03, 2004 at 23:14 UTC
    This is why you are getting the uninitialized error.

    On line 8, you are simply declaring your variables. As the Camel book explains, when you use "my" to declare variables, they default to undef. In lines 17-28, if the hash values are empty, they will return undef.
    You can correct this by explicitly assign a value to each variable on line 8 or by testing the variable assignment values on lines 17-28 before trying to print them on line 33.

    hope this helps,
    davidj

      I think that explanation is misleading. If what you say were true, I would expect this test to pass:

      use Test::More tests => 1; my %empty_hash; my $value = 1; $value = $empty_hash{empty_value}; is( $value, 1, 'undef from hash should not overwrite defined value' );

      Your second option (testing the definedness of the hash value assignments) is correct, though.

        Maybe I am missing something here. Why should undef from a hash not overwrite a defined value? When I code something like

        $value = $empty_hash{empty_value};

        and $empty_hash{empty_value} has not been defined, $value will certainly get assigned undef since undef is the return value of the attemped hash reference. Or is it that a return value from a hash reference getting assigned is conditional upon the hash value being defined?
        If I am wrong, please let me know because I have always thought otherwise.

        davidj
Re: help with strict
by Anonymous Monk on Jun 03, 2004 at 23:19 UTC
    Just add the folloowing lines to your code:
    my @vars = ($mdy, $nomname, $nomemail, $nominst, $submitname, $submitemail, $submitcat, $submitinst, $submitdiv, $mentor, $ptcare, $clinres, $comments); print $_ || "Variable has no value\n" for(@vars);
Re: help with strict
by Plankton (Vicar) on Jun 03, 2004 at 22:47 UTC
    You could do something like this ...
    $ export ENVONE=HI_THERE $ env | grep ENV ENVONE=HI_THERE $ cat notset.pl #!/usr/bin/perl -w use strict; my $envOne = $ENV{'ENVONE'}; my $envTwo = $ENV{'ENVTWO'}; print "ENVONE=" . ($envOne||"Is not set") . "ENVTWO=" . ($envTwo||"Is not set") . "\n"; $ ./notset.pl ENVONE=HI_THEREENVTWO=Is not set

    Plankton: 1% Evil, 99% Hot Gas.
Re: help with strict
by cyocum (Curate) on Jun 04, 2004 at 11:35 UTC
    i'm not sure what i might have inadvertantly added or deleted

    There are some great tools to figure this out. On a Unix/Linux machine you can use the command line tool diff. On Windows, there is WinDiff. These tools are very useful if you use some kind of source control even if it is just making a new copy of the file every time you change something.

    As for your other problems, they have been very well treated in the other nodes in this thread. I hope this helps.

Re: help with strict
by Anonymous Monk on Jun 04, 2004 at 16:25 UTC
    Thank you all for your time and helpful advice (although I am baffled by Plankton's response! what does it mean?!?)
    it turned out, in the end, that my problem was actually that one of the variables that i was trying to print out simply didn't exist - it never was one of the params that got passed to the script from the form i'm using. so that was simple. (there is no param called "SUBMITINST").

    oddly enough, though, when i ran Anonymous Monk's snippet to spit out all the $vars, it ignored that?

    i'm left with the question: "why does the compiler recognize that $submitinst as undef in line 33, but not in line 23? i.e. why didn't it complain that $in{SUBMITINST} was undef?

    and thanks also to Ovid (whose tutorials i love!!) for pointing out that i can just use the hash values, rather than transferring them into new scalars. that cleans things up a lot!
      sorry - this last "Anonymous Monk" was really me, giving some rather overdue followup. thanks again!!
Re: help with strict
by shonorio (Hermit) on Jun 04, 2004 at 02:45 UTC
    Why you are using single quote on line 33 ? I think you do not need this, try to remove the single quote and use only this:
    33 print "($mdy,$nomname,$nomemail,$nominst,$submitname,$submitemail, $submitcat,$submitinst,$submitdiv,$mentor,$ptcare,$clinres, $comments)";

    Solli Moreira Honorio
    Sao Paulo - Brazil

      What leads you to believe that this will solve the supplicant's problem?

      The single quotes have no semantic meaning to perl when it parses the string, but they may be meaningful to the programmer who reads the output.

        Sorry, I misunderstand the problem and wrotte shit. You are 1000% right.

        Solli Moreira Honorio
        Sao Paulo - Brazil