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

I find myself doing:
if (defined($params->{root}) && $params->{root} eq '')
to avoid a runtime warning.
Always having to check if the variable is defined before testing its value. It just seems soooo unnecessarily verbose.
Is there a better way? I feel I'm missing something (with respect to my knowledge).

Replies are listed 'Best First'.
Re: complaint: always testing defined()
by ysth (Canon) on Nov 02, 2007 at 04:17 UTC
    This doesn't work in your example, where you are specifically testing for a false value, but in other cases, you can do:
    if ( ($params->{root} || '') eq 'foo' )
    The other thing to consider is why you have so many possible undefs; could you be initializing things, providing default values, using NOT NULL columns, etc. to avoid the possibility of undefs in some cases?
      But please note that you can't use this to compare to '0', or any other value that evaluates to false in a boolean context, so you should only use it to compare it with constants.

      perl -wle 'if( ("0" || "") eq "0"){print "yes"} else { print "no" }' no

        It seems // (binary defined-or operator) isn't popular enough for some reason (available at least in 5.8.8) ...

        my $p; $p //= 2; my $q = 0; $q //= 2; print $p , $q; # 20

        A few minutes later... Well, above isn't available by default in 5.8.8 but via separate patch. It seems the patch isn't popular enough for some reason.

        :)

      Good point. It's form input. I should just provide defaults. I knew there was something obvious I was missing this morning :)

      Thanks.

Re: complaint: always testing defined()
by Joost (Canon) on Nov 02, 2007 at 13:44 UTC

      I would advice against using and in this context, because later someone (you) may add an innocent return ....

      sub is_empty_string { my ($value) = @_; return defined $value and $value eq ''; }

      I think && is more appropriate here:

      sub is_empty_string { my ($value) = @_; return defined($value) && $value eq ''; }
Re: complaint: always testing defined()
by apl (Monsignor) on Nov 02, 2007 at 09:50 UTC
    The construction I use (after invoking GetOpt to return $flag) is:

                $flag = 0 if !$flag;

    I'm certain there are better ways (and I look forward to reading about them).

      $flag||=0; is faster :)

      Oha

        It also has the grace of shaving 7 characters off ones golf score... 8-)
      This is one of the rare instances where I'd find unless more acceptable
      $flag = 0 unless $flag;

      Update: s/ flag/ $flag/

Re: complaint: always testing defined()
by Anonymous Monk on Nov 02, 2007 at 20:08 UTC
    no warnings "uninitialized"; # then it's just a regular check if ($params->{root} eq '') ...

        OP is checking for defined-ness solely to avoid generation of the warning (if the variable being checked against the empty string happens to be undefined). To me, that is whole reason for existence of this thread (from OP)...

        I find myself doing:
        if (defined($params->{root}) && $params->{root} eq '')
        to avoid a runtime warning.