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

Friends,

I am having trouble dealing with 0 in certain cases. Here are a few snippts and what bugs me about them.
... my $MISC_FILE_DIR = shift || die usage(); my $req = shift || die usage(); my $inqfile = shift || die usage(); my $sent = shift || die usage(); my $status = shift || die "please specify status\n" . usa +ge(); ...
Zero is a valid value for status but how do I keep it from be treated like undef? Here's what happens when I use zero on the command-line.
bash-2.03$ insertIntoLN.pl misc 135 doesnt_matter 20031208120000 0 please specify status usage: ./insertIntoLN.pl <miscdir> <req> <inqfile> <sent> <status>
Also when I pull data out of the database zero seem to be treated as undef. Example)
... while( my @row = $sth->fetchrow_array ) { print join( '|', map ( $_ || 'NULL', @row )) ."\n"; } ...
Output I get is ...
137|src/20031208153031.txt|20031210093234|NULL|NULL 138|src/20031208153031.txt|20031210093509|NULL|NULL
... I was expecting the last column to be 0. What am I not getting here?
Thanks

Plankton: 1% Evil, 99% Hot Gas.

Replies are listed 'Best First'.
Re: zero vs undef
by Abigail-II (Bishop) on Dec 09, 2003 at 17:09 UTC
    You are using || which tests for truth. 0 is false. Either use defined, or upgrade to 5.8.2 and install the defined-or patch, in which case you can replace your ||'s with //'s to get the results you intend.

    Abigail

      When will the defined-or patch be part of the main source? I don't want to install it on the machines I have at work because I want to keep the patches I have to re-apply to a minimum (right now, it's none and I like it that way).

      ------
      We are the carpenters and bricklayers of the Information Age.

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

        When will the defined-or patch be part of the main source?
        It *is* part of the main source. But only in the development track, so if you want to run 'patch' only 0 times, you have to wait till 5.10.

        Abigail

Re: zero vs undef
by Aristotle (Chancellor) on Dec 09, 2003 at 17:14 UTC
    Change your conditionals. There's a myriad conditions your can use to your advantage: in the first case, since you're pulling the parameters off one by one you can check for whether @ARGV still has elements:
    my $MISC_FILE_DIR = @ARGV ? shift : die usage(); # ... # ...
    But I'd rather write that piece as
    die usage() if @ARGV < 5; my ($MISC_FILE_DIR, $req, $inqfile, $sent, $status) = @ARGV;
    Your second situation requires the canonical fix, a test of definedness:
    while( my @row = $sth->fetchrow_array ) { print join( '|', map ( defined() ? $_ : 'NULL', @row )) ."\n"; }

    Makeshifts last the longest.

Re: zero vs undef
by duff (Parson) on Dec 09, 2003 at 17:10 UTC

    Check for definedness rather than truth. I don't usually run into this problem, but here's a solution I just made up on the spot. Caveat lector!

    my $MISC_FILE_DIR = defined($_=shift) ? $_ : die usage(); my $req = defined($_=shift) ? $_ : die usage(); my $inqfile = defined($_=shift) ? $_ : die usage(); my $sent = defined($_=shift) ? $_ : die usage(); my $status = defined($_=shift) ? $_ : die "please specify + status\n" . usage();

    Another solution might be to use length to see if there's something other than an empty string there (undef evaluates to '' in a string context)

    You could also lobby for the // operator to somehow make it into perl5. // is the "defined or" in perl 6 and would be used like this: my $MISC_FILE_DIR = shift // die usage();

Re: zero vs undef
by Roy Johnson (Monsignor) on Dec 09, 2003 at 17:16 UTC
    The minimal change solution:
    defined(my $MISC_FILE_DIR = shift) || die usage(); #etc
    A possible alternative:
    @ARGV == 5 or die usage();
    Your database problem is the same: there's a difference between undef and zero, but not to ||. If you have the // patch, you could use that. Otherwise, you need to call defined() instead of relying on the Boolean value of an expression.

    The PerlMonk tr/// Advocate