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

Melodious Monks,

As a good perl coder should almost always do, I always start my programs with '-w' and 'use strict', which ensures that I'm easily caught when I make stupid mistakes! Unfortunately, I beat my head against the wall the other day for about 30 minutes trying to debug a DBI query, before realizing that I had a typo in my execute statement.

Much to my amazement, there was no warning thrown telling me something to the effect of 'use of uninitialized value in hash element' thrown when calling code such as the following:
#!/usr/local/bin/perl -w use strict; use DBI; my $user = $ARGV[0]; my $pass = $ARGV[1]; my $dbh = DBI->connect('DBI:mysql:database=test;host=localhost', $user, $pass, { RaiseError => 1, AutoCommit => 1, PrintError => 1, } ); my $create_sql =<<SQL; CREATE TEMPORARY TABLE IF NOT EXISTS test_situation (id int, data +int) SQL $dbh->do($create_sql); my $sql = "SELECT * FROM test_situation WHERE id = ?"; my $sth = $dbh->prepare($sql); ## Notice array does not even contain element that I reference: my $href = { foo => 1, bar => 2, baz => 3, }; $sth->execute($href->{'id'}); ## Shouldn't this throw a warning?

Why?!? It was very frustrating when I realized that the problem was a mis-casing of one of the hash keys that I was using, and it was something that warnings would always catch.

Any clues?

Replies are listed 'Best First'.
Re: Warnings not being thrown with DBI
by pg (Canon) on Sep 11, 2005 at 00:33 UTC

    It is the design decision for DBI module, to use Perl undef to represent SQL NULL. You need something to represent SQL NULL in Perl, and I do see undef as a reasonable choice for that matter.

Re: Warnings not being thrown with DBI
by jZed (Prior) on Sep 11, 2005 at 00:15 UTC
    Perl does not complain because there is a hash value whose key is 'id' (it autovivifies when you mention it). DBI doesn't complain because undef (NULL) is a valid thing to send as a parameter to execute.

    update : See discussion on autovivification below.

      That's not autovivification. if you print dumper the hash, there is still no id after the execute() call.

      Nit: It's not autovivified.

      my $href = {}; my $id = $href->{id}; print((%$href ? "not empty" : "empty"), "\n"); __END__ output ====== empty

      Hash entries are never autovified.

        Nit: Never say "never":

        main->execute( $href->{id} ); sub execute { for( @_ ) { die if $_->{none}; } } print keys %$href, $/;

        (prints "id")

        - tye