Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

if not defined

by Trihedralguy (Pilgrim)
on Mar 23, 2007 at 17:52 UTC ( [id://606305]=perlquestion: print w/replies, xml ) Need Help??

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

This is an interesting, but simple question regarding a statement I'm trying to use. Basically, it runs after an sql (while) statement and if that isn't defined, it doesn't pull results, thus leaves a blank. So basically after the sql pull I want to do a
if (not defined($pname) && $pname ne '' && defined($policy_ur) && $pol +icy_ur ne '' && not defined($odate) && $odate ne '') {

The problem is that i don't think Not Defined is a command that CGI/Perl understands. Could I be wrong, yes. Is it even possible to do an not defined.

Replies are listed 'Best First'.
Re: if not defined
by agianni (Hermit) on Mar 23, 2007 at 18:11 UTC

    not defined is absolutely valid Perl. Just be careful about precedence . Note that ! and not both mean not, but have varying precedence. So if you're going to use the not form, you should probably also use the and form of the AND operator, as && has a higher precedence than not, but and has a lower precedence, which is likely causing you trouble in your example. When in doubt, use parenthesis.

    If you find this confusing, consider reading this Perl Journal article on the topic by Domimus, which covers the topic nicely.

    perl -e 'split//,q{john hurl, pest caretaker}and(map{print @_[$_]}(joi +n(q{},map{sprintf(qq{%010u},$_)}(2**2*307*4993,5*101*641*5261,7*59*79 +*36997,13*17*71*45131,3**2*67*89*167*181))=~/\d{2}/g));'
Re: if not defined
by Eimi Metamorphoumai (Deacon) on Mar 23, 2007 at 18:15 UTC
    not defined is fine, but not is very low precedence. That is,
    if (not defined($pname) && $pname ne ''){
    is parsed the same as
    if (not (defined($pname) && $pname ne '')){
    instead of
    if ((not defined($pname)) && $pname ne ''){

    Also, if $pname isn't defined, then it can't possibly equal '', so you probably need to change your conditions a bit (probably you mean something like

    if (!defined($pname) || $pname eq ''){
    but it's possible you want something else.)
Re: if not defined
by Old_Gray_Bear (Bishop) on Mar 23, 2007 at 18:01 UTC
    if (!defined $pname) { do something with $pname } else { do something in the way of a polite error message }

    ----
    I Go Back to Sleep, Now.

    OGB

      No need to switch to !, not is legal Perl.

        But there is a precedence problem
        if (not defined($pname) && $pname ne '')
        means
        if (not (defined($pname) && ($pname ne '')))
        while
        if (!defined($pname) && $pname ne '')
        means
        if ((!defined($pname)) && ($pname ne ''))

        The OP wants
        if (!defined($pname) && $pname ne '')
        or
        if ((not defined($pname)) && $pname ne '')

Re: if not defined
by TGI (Parson) on Mar 23, 2007 at 18:17 UTC

    Your problem is in operator precedence. After adding parenthesis to match precedence, you have:

    not ( ( ( ( ( defined($pname) && $pname ne '' ) && defined($policy_ur) ) && $policy_ur ne '' ) && not defined($odate) ) && $odate ne '' )

    I think you want to use the higher precedence logical not operator (!). That way your condition will work out to this:

    ( ( ( ( (!defined($pname) && $pname ne '') && defined($policy_ur) ) && $policy_ur ne '' ) && not defined($odate) ) && $odate ne '' )


    TGI says moo

      I'd say the former (resembeling the OP) makes sense:

      It's testing for all vars at first if it is defined and then if it also isn't the empty string. This partial results is inverted for $odate and then chained on the same level. The result of that is inverted by the leading "not".

      If you ignore the (possible) warnings, when a string function is applied to undef

      !(length($pname) && length($policy_ur) && !length($odate))
      will yield the same.

      That may be what he wants or not.

      Your (!defined($pname) && $pname ne '') on the other hand is only true für $pname being "undef", so contains a redundant test.

Re: if not defined
by pKai (Priest) on Mar 23, 2007 at 18:10 UTC
    For one, it's valid Perl syntax:
    D:\Temp>perl -c -e "if (not defined($pname) && $pname ne '' && defined +($policy_ur) && $policy_ur ne '' && not defined($odate) && $odate ne +''){}" -e syntax OK
    But it's probably not doing what you expect:
    D:\Temp>perl -MO=Deparse,p -e "if (not defined($pname) && pname ne '' +&& defined($policy_ur) && $policy_ur ne '' && not defined($odate) && +$odate ne ''){}" if (not defined $pname && $pname ne '' && defined $policy_ur && $polic +y_ur ne '' && !(defined $odate && $odate ne '')) { (); } -e syntax OK
    not has a much lower precedence than &&

    use either not and and or ! and && in conjunction to get the intended effect.

    Update: Seems like newly accuired syntax highlighting was distracting me ;-). Though a little bit complicated the assembly of the leading not (inverting the result of the whole test) with the && (chaining all the inner sub-tests together) makes sense.

Re: if not defined
by andye (Curate) on Mar 23, 2007 at 18:17 UTC
    Sure. You have a choice of:

    ! defined

    which is high precedence, or

    not defined

    which is low precedence. If you don't want to have to think about precedence, just use loads of brackets.

    You can read more about this in: perlop.

    By the way, you mention CGI: it doesn't make any difference whether the Perl script is being used for a website (CGI), or not. The language remains the same.

    Hope that helps, andye

Re: if not defined
by ikegami (Patriarch) on Mar 23, 2007 at 19:46 UTC
    If there's no difference between undef and the nul string (""), you could canonize the values.
    for ($pname, $policy_ur, $odate) { if (!defined($_)) { $_ = ''; } } if ($pname ne '' && $policy_ur ne '' && $odate ne '') { ... }
    Or the other way around:
    for ($pname, $policy_ur, $odate) { if (defined($_) && $_ eq '') { undef $_; } } if (!defined($pname) && !defined($policy_ur) && !defined($odate)) { ... }
Re: if not defined
by Trihedralguy (Pilgrim) on Mar 23, 2007 at 18:18 UTC
    Thats very odd that you have to do either "not..and" or "!..&&".
    if (not defined($pname) and $pname eq '' && defined($policy_ur) and $p +olicy_ur eq '' and not defined($odate) && $odate eq'') {

    That works famously! - Thanks everyone and pKai :)

      Is this really what you mean?

      ( ( ( not defined($pname) ) and ( $pname eq '' && defined($policy_ur) ) ) and $policy_ur eq '' ) and ( not ( defined($odate) && $odate eq'' ) )

      Please take the time to read about operator precedence. That perl has logical operators with two levels of precendence is very useful, but it is a trap for the unwary or unaware.

      If you don't pay attention to precedence you'll think the answer to 2+3*5 is 25. Even worse, if you have code to implement X+Y*Z that uses bad precedence, and you test your code with X, Y and Z all being 1, you'll believe the code works. Then six months later, Bob in accounting is wanting to know where $5 million went...


      TGI says moo

      hm,
      ... and not defined($odate) && $odate eq '')
      is testing if it's "not defined" (i. e. undef) and then if it's also equals the empty string.

      Thinking about it, both can never be true at the same time.

      Update: Oh well, twice in a row on the wrong track. :-(

      TGI has the precedence right and the problem lies in the first part, not in the second I cited.

Re: if not defined
by Trihedralguy (Pilgrim) on Mar 23, 2007 at 18:08 UTC
    That doesn't appear to work:

    if (!defined $pname && !defined $policy_ur && !defined $odate)


    The values ARE defined.

      The above condition is not equivalent to what you posted earlier.

      NOT( DEFINED(A) AND DEFINED(B) AND DEFINED(C) ... )
      is equivalent to:
      ( NOT DEFINED(A) ) OR ( NOT DEFINED(B) ) OR ( NOT DEFINED(C) ) ...

      That's De Morgan's theorem.


      TGI says moo

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://606305]
Approved by pKai
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (5)
As of 2024-04-19 00:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found