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

I have this bit of opening code for a CGI script--actually, I have it in many scripts.

#!/usr/bin/perl -w use strict; use CGI qw/:standard/; my $q = new CGI; my $choice = param('choice') || 1;

This works just fine until recently when I tried to pass a parameter value of 0 (i.e., script.cgi?choice=0). If I give it zero within quotes (i.e., script.cgi?choice='0'), it works. Otherwise, the value reverts to the default of 1.

It seems to be thinking that 0 is nothing. Is there any way that I can tell it to accept 0 through the web browser and to only use the || value when results are null? Or do I have to reverse my script after this parameter and make the default 0? Another possibility would be to put the value in quotes when sending it from the previous script. I guess that would be easy enough. I'm just wondering if there's a notation to param() that I could use instead.

-Spenser

That's Spenser, with an "s" like the detective.

Replies are listed 'Best First'.
Re: param = 0, not NULL
by davorg (Chancellor) on Mar 29, 2007 at 13:13 UTC
    use CGI qw/:standard/; my $q = new CGI; my $choice = param('choice') || 1;

    This has nothing to do with your question but you seem slightly confused by the function-based and OO interfaces to CGI.pm. You're creating a CGI object, but then ignoring it to use the function-based interface. You don't need that my $q = new CGI;.

    As for your problem, your code is just doing what you are telling it to do. Your code is saying "set $choice to the parameter 'choice', unless that parameter has a false value, in which case set $choice to be 1". 0 has a false value, so if you send a parameter of 0 then you'll end up with 1.

    You need to understand the difference between a value being "defined" and a value being "true". Here, you are interested in whether the parameter is defined, not whether it is true.

    In the forthcoming Perl 5.10, there is a new "defined-or" operator that does exactly what you want. So you'll be able to write:

    my $choice = param('choice') // 1;

    But that's not out yet, so you'll have to do something like this:

    my $choice = param('choice'); $choice = 1 unless defined $choice;
    --

    See the Copyright notice on my home node.

    "The first rule of Perl club is you do not talk about Perl club." -- Chip Salzenberg

Re: param = 0, not NULL
by shigetsu (Hermit) on Mar 29, 2007 at 13:09 UTC
    my $choice = param('choice') || 1;
    could be written as
    my $choice = defined param('choice') ? param('choice') : 1;
Re: param = 0, not NULL
by f00li5h (Chaplain) on Mar 29, 2007 at 13:07 UTC

    Actually, it thinks 0 is not true. As it happens, it isn't.

    The following are all not true: undef, 0, "", "0" and by extension the empty list and from that, an empty hash.

    @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print;
      This is interesting.. an empty hash is false, but an empty hash reference.. is TRUE. :-)
      #!/usr/bin/perl -w my %hash = (); %hash or print "empty hash is false\n"; my $hash = {}; print "empty hash ref is true\n" if $hash ;

        There is no such thing as an "empty hash reference". Or, if there is then the only possible meaning that it could have would be an undefined scalar.

        I think you mean "a reference to an empty hash is TRUE". And that's because Perl has already allocated storage for the hash and given you a reference to it. And a reference is always true.

        --

        See the Copyright notice on my home node.

        "The first rule of Perl club is you do not talk about Perl club." -- Chip Salzenberg

Re: param = 0, not NULL
by Ojosh!ro (Beadle) on Mar 29, 2007 at 15:41 UTC

    undef, 0 and '' will all cause the default value to be set. The simplest way to check whether your param( 'choice' ) has any or no value is the use of defined

    my ( $a, $b, $c ) = ( 0, '', undef ); print defined $a, " -0-\n"; # prints 1 -0- print defined $b, " --\n"; # prints 1 -- print defined $c, " undef"; # prints 0 undef

    Hope it helps.

    if( exists $aeons{strange} ){ die $death unless ( $death%2 ) }
Re: param = 0, not NULL
by Moron (Curate) on Mar 29, 2007 at 15:23 UTC
    The || operator evaluates '0' as false. You appear from your comments to want to check the length rather than the Perl logical value, e.g.:
    #!/usr/bin/perl -w use strict; use CGI qw/:standard/; my $q = new CGI; my $choice = param('choice'); length( $choice ) or $choice = 1;

    -M

    Free your mind

Re: param = 0, not NULL
by Burak (Chaplain) on Mar 30, 2007 at 10:33 UTC
    I'm using " defined $thing && $thing ne '' " stuff too much, so, I've wrapped this in a sub :)
    sub zot ($) { # zero_or_true defined($_[0]) && $_[0] ne ''; } # later... my $choice = zot param('choice') ? param('choice') : 1;
    HTH