in reply to Re^6: Regex result being defined when it shouldn't be(?)
in thread Regex result being defined when it shouldn't be(?)

I'm wondering if, by focusing on the sysseek aside, you've missed the point about the return value of defined() itself. It returns something that is indistinguishable from the return value of the == operator. See below.

#!/usr/bin/perl -l use strict; use warnings; use Devel::Peek; sub display { my $text = shift; my $result = shift; my $ans = ($result) ? 'TRUE' : 'FALSE'; print STDERR "$text => CONDITIONAL WAS $ans"; Dump $result; print STDERR '-'x20, "\n"; } my @results; push @results, ['1==1', 1==1]; push @results, ['defined("x")', defined 'x']; push @results, ['defined("x")==1', defined('x')==1]; push @results, ['defined("x")eq"1"', defined('x')eq"1"]; push @results, ['1==0', 1==0]; push @results, ['defined(undef)', defined undef]; push @results, ['!defined(undef)', !defined undef]; push @results, ['defined(undef)==0', defined(undef)==0]; push @results, ['defined(undef)eq""', defined(undef)eq""]; display(@$_) for ( @results ); __END__ 1==1 => CONDITIONAL WAS TRUE SV = PVNV(0x5de5c8) at 0x479ab8 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x47c3e8 "1"\0 CUR = 1 LEN = 10 -------------------- defined("x") => CONDITIONAL WAS TRUE SV = PVNV(0x5de5c8) at 0x479ab8 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x47c3e8 "1"\0 CUR = 1 LEN = 10 -------------------- defined("x")==1 => CONDITIONAL WAS TRUE SV = PVNV(0x5de5c8) at 0x479ab8 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x47c3e8 "1"\0 CUR = 1 LEN = 10 -------------------- defined("x")eq"1" => CONDITIONAL WAS TRUE SV = PVNV(0x5de5c8) at 0x479ab8 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x47c3e8 "1"\0 CUR = 1 LEN = 10 -------------------- 1==0 => CONDITIONAL WAS FALSE SV = PVNV(0x5de5c8) at 0x479ab8 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 0 NV = 0 PV = 0x47c3e8 ""\0 CUR = 0 LEN = 10 -------------------- defined(undef) => CONDITIONAL WAS FALSE SV = PVNV(0x5de5c8) at 0x479ab8 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 0 NV = 0 PV = 0x47c3e8 ""\0 CUR = 0 LEN = 10 -------------------- !defined(undef) => CONDITIONAL WAS TRUE SV = PVNV(0x5de5c8) at 0x479ab8 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x47c3e8 "1"\0 CUR = 1 LEN = 10 -------------------- defined(undef)==0 => CONDITIONAL WAS TRUE SV = PVNV(0x5de5c8) at 0x479ab8 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x47c3e8 "1"\0 CUR = 1 LEN = 10 -------------------- defined(undef)eq"" => CONDITIONAL WAS TRUE SV = PVNV(0x5de5c8) at 0x479ab8 REFCNT = 1 FLAGS = (IOK,NOK,POK,pIOK,pNOK,pPOK) IV = 1 NV = 1 PV = 0x47c3e8 "1"\0 CUR = 1 LEN = 10 --------------------

By doing an explicit test against a single value, rather than leaving defined() to return a "truthy" value itself, future readers would be well within their rights to infer that defined() may return one of many integers (~4billion in 32bit world, ~18 billion billion in 64bit world, ...) or one of an infinitude of possible strings, and that compared value of 0 or "" is somehow magically important, without any indication that the importance comes because the function is returning a Boolean (or at least something that can be interpreted in a truthy manner). On the other hand, if you left !defined($var) as the sole element of the conditional, you would show you expect the return from defined() function to be truthy (Boolean), and are using it as such. To me, this is more clear than the comparison to the magic number (or magic string). But if you're the only person who will ever read your code, and you are 100% certain that perl will never change the false return to be 0|"0" instead of 0|"", then continue as you want. In which case, I'd recommend the defined($var)==0 rather than defined($var) eq '', because it seems more future proof, and programmers from other languages are possibly more accustomed to integers being mildly truthy (for example, c's if(5) evaluating true) than they would be to strings evaluating true.

(BTW: Sorry about my use of -1 in an earlier post: I had misremembered that c defaulted to -1 for TRUE... But before making this post, I did a quickie in gcc, and saw that 1==1 really did return 1. Maybe I'm remembering some ancient compiler I used 20+ years ago. Or my memory is making this up.)

Replies are listed 'Best First'.
My memory isn't as bad as I thought (Re^8: Regex result being defined when it shouldn't be(?))
by pryrt (Abbot) on Oct 23, 2018 at 19:46 UTC

    A year ago, I said:

    (BTW: Sorry about my use of -1 in an earlier post: I had misremembered that c defaulted to -1 for TRUE... But before making this post, I did a quickie in gcc, and saw that 1==1 really did return 1. Maybe I'm remembering some ancient compiler I used 20+ years ago. Or my memory is making this up.)

    I finally figured it out.

    I recently rescued and resurrected my family's old TI99-4/A (Mom was about to sell it in a garage sale!), and was reminded: In TI-BASIC, TRUE is represented by -1. You can go to http://js99er.net/, select TI BASIC, and type PRINT 1=1 to see that oddity for yourself.

      I have a dim memory of seeing #define TRUE (-1) somewhere, and IIRC, the accompanying documentation explained how that value was used because even if you mask it with an & or shift the value, it's still true. Haven't seen it anywhere since then, though.

      Good old TI99-4/A ... after 4 hours of usage I had to put an ice pack on top to cool it down ...

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re^8: Regex result being defined when it shouldn't be(?)
by chenhonkhonk (Acolyte) on Nov 16, 2017 at 18:37 UTC
     defined($var)==0
    Use of uninitialized value in numeric eq (==)

    use strict; use warnings; my $variable = undef; if( undef == 0 ){ print "undef == 0\n"; } if( $variable == 0 ){ print "\$variable undef == 0\n"; } if( "" == 0 ){ print "\"\" == 0\n"; } if( undef eq 0 ){ print "undef eq 0\n"; } if( undef eq 0 ){ print "\$variable undef eq 0\n"; } if( undef eq "" ){ print "undef == \"\" \n"; } if( 0 == "0" ){ print "0 == \"0\"\n"; } if( 0 eq "" ){ print "0 eq \"\""; } if( undef eq "" ){ print "undef == \"\"\n"; } if( defined ($variable) eq "" ){ print "undef == \"\"\n"; } exit 0;
    The last two cases may be of particular interest. undef is uninitialized as itself or from a variable, but as the result of defined it is not uninitialized. Magic conditions. I'm running Perl 5.26.1

    Nvm: doy. Defined returns "" on undef.
      defined($var)==0
      Do you also write conditios as
      if ( ($var < $threshold) == TRUE ) ...
      ? Then why not
      if ( ( ($var < $threshold) == TRUE ) == TRUE ) ...
      or more?