in reply to "defined" function fails to evaluate expression; feature or fault?

It's not a feature or bug, it just is :)

defined() returns a bool, (either false/true) when it evaluates something, so when you do this: defined ($x || $y);, it's not doing what you think it does.

Here's an example that illustrates the issue:

perl -wMstrict -E 'my $x = defined $ARGV[5]; say defined $x' 1

Now, $ARGV[5] is not set in any way, but since we're returning the value of the call to $x, $x will most definitely be defined, because it now evaluates to false as the variable was not defined (define() returns false, if something wasn't defined).

You need to call a define on each side of the comparison operator:

my $x = defined $x || defined $y;

...as per your solutions that work. Then, check $x for truth:

die "blah...\n" if ! $x;

...or combined:

die "blech...\n" if ! defined $x || defined $y;

Replies are listed 'Best First'.
Re^2: "defined" function fails to evaluate expression; feature or fault?
by AnomalousMonk (Archbishop) on Jan 26, 2017 at 21:08 UTC

    Not that it makes any difference in this case, but defined returns  '' (the empty string; false) or  1 (true):

    c:\@Work\Perl>perl -wMstrict -le "print 'perl version ', $]; ;; print 'undefined A: >', defined(), '<'; print 'undefined B: >', defined(undef), '<'; print 'defined: >', defined(42), '<'; " perl version 5.008009 undefined A: >< undefined B: >< defined: >1< perl version 5.014004 undefined A: >< undefined B: >< defined: >1<


    Give a man a fish:  <%-{-{-{-<

      Hi AnomalousMonk,

      defined returns '' (the empty string; false) or 1 (true)

      To be even more specific, Perl has a "special" value for "false" - see Truth and Falsehood.

      The difference between an empty string and the special "false" value:

      $ perl -wMstrict -le 'my $x=""; print 3+$x;' Argument "" isn't numeric in addition (+) at -e line 1. 3 $ perl -wMstrict -le 'my $x=!!""; print 3+$x;' 3 $ perl -wMstrict -le 'my $x=defined(); print 3+$x;' 3

      And looking even more closely with Devel::Peek:

      Regards,
      -- Hauke D

      Update 2019-08-17: Updated the link to "Truth and Falsehood".

      Yep, I caught that after doing some testing, and had updated my reply (at least I thought I fixed it all).

      Thanks for the heads-up, as if someone is expecting a zero and is getting the empty-string type false instead, it could cause head-scratching.