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

Good day Monks,

I am trying to determine if what I am doing is appropriate or if there are easier/better ways. I have a huge variable list that is broken down into scalars, arrays and hashs. I am extracting those values from xml documents that are non-standard and differ one to another so the variables from one document to another may or may not have data present. When passing variables that may be undef or "" (empty) values, I am trying to make sure the field in which the variable will populate into a database contains "null". Not for a particular requirement but because I fear that somewhere through the code an array value is missing and therefore shifts the value of another field into a placeholder of a different field. I understand that if I were a Monk I would have probably been able to figure out a more elegant way to maintain such field integrity but unfortunately I am not capable at this point. Thus I am going to use the following function to populate a "null" value into undef or empty variables and wanted to know if an obvious problem may exist with solution or is there an easier way to accomplish the same task? My assumption is that undef variables would be translated into "" (empty string) upon its use within Perl and not require the use of the defined function. Thanks in advance for any responses.

Danny

use strict; my $out; my $COUNT = 0; my $PORT = undef; my $PATH = "/usr/local"; my $CODE = ""; my $COUNT = ifnil($COUNT); my $PORT = ifnil($PORT); my $PATH = ifnil($PATH); my $CODE = ifnil($CODE); print "COUNT: $COUNT\nPORT: $PORT\nPATH: $PATH\nCODE: $CODE\n"; sub ifnil { my ($value) = @_; my $null = "null"; if ( $value eq "" ) { $out = $null; } else { $out = $value; } return $out; }

Replies are listed 'Best First'.
Re: undef and empty variables
by tilly (Archbishop) on Jan 19, 2011 at 16:57 UTC
    If you are not using warnings, then indeed undef will be translated into "".

    However you should use warnings because it will catch other things, and so should include the defined check to avoid that warning. Furthermore think carefully about your data. It could be that "" is a valid value. Therefore my natural inclination would be to keep "" as a valid value, and map undef to null.

      Howdy!

      Depending on the RDBMS, the empty string may not be distinguished from NULL. Oracle leaps instantly to mind as one which explicitly documents their equivalence between an empty string and NULL. That's not standards compliant, but it's Oracle.

      yours,
      Michael
        That is one of the reasons that I said "think carefully about your data" instead of "null and empty string ar different".
Re: undef and empty variables
by ikegami (Pope) on Jan 19, 2011 at 17:02 UTC

    I am trying to make sure the field in which the variable will populate into a database contains "null".

    A NULL, or the string "null"? The following will convert empty strings to undef which database modules view as NULL.

    sub empty_to_undef { return defined($_[0]) && !length($_[0]) ? undef : $_[0]; }

    or

    sub empty_to_undef { no warnings 'uninitialized'; return length($_[0]) ? $_[0] : undef; }

    My assumption is that undef variables would be translated into "" (empty string) upon its use within Perl and not require the use of the defined function.

    Undef does stringify to the empty string, but a warning is issued when this happens. Disabling this warning globally is unwise, though.

Re: undef and empty variables
by JavaFan (Canon) on Jan 19, 2011 at 17:20 UTC
    If you're using the DBI, and using place holders, most drivers will insert a NULL if the corresponding value is undefined.
Re: undef and empty variables
by sundialsvc4 (Abbot) on Jan 19, 2011 at 18:16 UTC

    It is my understanding that undef always becomes NULL, and that the handling of “an empty string” may vary.   (Database drivers tend to try to second-guess that situation, and the outcome is typically not that bad ...)

    Nevertheless, bear in mind that, in an array, undef is “a value.”   The slot is occupied, although the value in that slot may be undef.

      Thinking further about exactly how I would write this ... I would pass a hashref containing the parameter values, to a sub that would perform the query.   The SQL string would use placeholders, and the corresponding array of parameter-values would contain expressions that pulled keys from the hashref ... by name.   Any non-existent key would produce undef automagically.

      My sub would also contain error checks.   If the hashref was supposed to contain certain keys and perhaps to have non-empty values for those keys, my routine would expressly check for this and would croak if something was not right. (Thus, “the fact that the program did not croak” tells me positively that the error condition I was testing for does not exist ... “therefore, the bug must be somewhere else.”)   The code would go straight into production with those error-checks in place.