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

Hello: I've got a subrutine that I want to use to check to see if one of three variable combinations are in use. If not one of these, it will print an error message. However, if I set the variables to the proper combination, I'm still erroring Out. Thanks:
sub chkfmt { if ( !(($DISCPCNT ne "") and ($DISCDAYSDUE ne "") and ($NETDAYSDUE ne "") +and (($DISCDUEDATE eq "") and ($NETDUEDATE eq "") and ($TERMSDISCAMT +eq "")) or !(($DISCDUEDATE ne "") and ($TERMSDISCAMT ne "") and ($DISCPCNT eq "") + and ($DISCDAYSDUE eq "") and ($NETDUEDATE eq "") and ($NETDAYSDUE eq + "")) or !(($DISCPCNT ne "") and ($DISCDUEDATE ne "") and ($DISCDAYSDUE eq "") +and ($NETDUEDATE eq "") and ($NETDAYSDUE eq "") and ($TERMSDISCAMT e +q "")) ) {print TSERROUT "If a discount is offered, Sports Authority wants o +ne of these formats:\n 1) Discount Percent, Discount Days Due, and Net Days Due.\n 2) Discount Due Date, and Discount Amount.\n 3) Discount Percent, and Discount Due Date.\n"; } }

Replies are listed 'Best First'.
Re: Set Combination
by Fastolfe (Vicar) on Nov 09, 2000 at 23:09 UTC
    Note that an empty string is equivalent to a 'false' value, while a populated one is 'true' (unless it evaluates to a numeric zero). You can also get rid of your !'s by reversing your AND/OR tests and negating the original terms:
    sub chkfmt { if ((!$DISCPCNT || !$DISCDAYSDUE || !$NETDAYSDUE || $NETDUEDATE || +$TERMSDISCAMT) || (!$DISCDUEDATE || !$TERMSDISCAMT || $DISCPCNT || $DISCDAYSDUE | +| $NETDUEDATE || $NETDAYSDUE) || (!$DISCPCNT || !$DISCDUEDATE || $DISCDAYSDUE || $NETDUEDATE || +$NETDAYSDUE || $TERMSDISCAMT)) { print TSERROUT "..."; } }
    Note that with all of these negation reversals in my head, I might have messed up your original logic. Take a look at that and see if you can follow it, making corrections as appropriate. Even if I got everything right in the translation, the code above still may not match what you're wanting if your original code was broken to begin with. Hope this helps.
Re: Set Combination
by b (Beadle) on Nov 09, 2000 at 23:07 UTC
    It's not clear how you set these variables. Maybe you should use exist() instead of eq ""

    Your code will look better if you change the !(...and...) to (...or...)

Re: Set Combination
by stephen (Priest) on Nov 09, 2000 at 23:51 UTC
    Might make it easier to catch the bug if you simplify the conditionals. You've got three basic conditions you're testing for here... why not break out their tests into their own subs?
    sub is_netdaysdue_format { return ($DISCPCNT ne "") && ($DISCDAYSDUE ne "") && ($NETDAYSDUE ne "") && ( ($DISCDUEDATE eq "") && ($NETDUEDATE eq "") && ($TERMSDISCAMT eq "") ); } sub is_discountamount_format { return ( ($DISCDUEDATE ne "") && ($TERMSDISCAMT ne "") && ($DISCPCNT eq "") && ($DISCDAYSDUE eq "") && ($NETDUEDATE eq "") && ($NETDAYSDUE eq "") ); } sub is_discountpercent_format { return ( ($DISCPCNT ne "") && ($DISCDUEDATE ne "") && ($DISCDAYSDUE eq "") && ($NETDUEDATE eq "") && ($NETDAYSDUE eq "") && ($TERMSDISCAMT eq "") ); }
    Then your test becomes:
    (is_netdaysdue_format() || is_discountamount_format() || is_discountpercent_format()) or print "Format must be..."

    stephen

    Updated: First revision sounded unintentionally irritating and too wordy.
RE: Set Combination
by mikfire (Deacon) on Nov 09, 2000 at 23:55 UTC
    You have three possible conditions in which you want to print this error message, but it seems one of them is out of control. Split the three clauses, as a debug measure, into three seperate statements and make the error message tell you what condition failed.
    sub chkfmt { unless ( $DISCPCNT and $DISCDAYSDUE and $NETDAYSDUE and !( $DISCDUEDATE or $NETDUEDATE or $TERMSDISCAMT ) ) { print TSERROR "First condition failed\n"; } unless ( $DISCDUEDATE && $TERMSDISCAMT && ! ( $DISCPCNT || $DISCDAYSDUE || $NETDUEDATE || $NETDAYSDUE ) ) { print TSERROR "Second condition failed\n"; } unless ( $DISCPCNT && $DISCDUEDATE && ! ( $DISCDAYSDUE || $NETDUEDATE || $NETDAYSDUE || $TERMSDISCAMT ) ) { print TSERROR "Third condition failed" }
    What I suspect you will find is some varaible you thought was (un)initialized actually (is)isn't. If it gets real bad, you can then take each error condition, test each variable and discover which one is behaving different than you expect. I will leave that as an exercise to the reader :)

    mikfire