sami.strat has asked for the wisdom of the Perl Monks concerning the following question:

I've got the following in a script I use:
if ($VAR1 != 2 || $VAR1 ne /^[+-]?\d+$/ ) { do something; }
If I turn on warnings, diagnostics, and strict I get the following errors:
[root@monitor app]# ./checker 10.175.193.55 Argument "External command error: Error in packet\nReason: (noSuch..." + isn't numeric in numeric ne (!=) at ./checker line 106 (#1) (W numeric) The indicated string was fed as an argument to an oper +ator that expected a numeric value instead. If you're fortunate the me +ssage will identify which operator was so unfortunate. Argument "External command error: Error in packet\nReason: (noSuch..." + isn't numeric in numeric ne (!=) at ./checker line 147 (#1) Controller Status Change Array Accelerator Battery
If I remove warning, strict, and diagnostics, the script works fine. Is there anything I can do to clean this script up such that I can leave strict, warning, and diagnotics in, without getting the error? Thanks in advance.

Replies are listed 'Best First'.
Re: if multiple conditions & Warinings....
by davido (Cardinal) on Aug 21, 2013 at 19:59 UTC

    Change it to :

    use Scalar::Util qw( looks_like_number ); if( ! looks_like_number( $VAR1 ) ) { do something... }

    If your definition of a number needs to be more restrictive than looks_like_number, let us know what we can do to help you refine the test further.

    Scalar::Util is a core module; it comes with Perl as part of the standard distribution.


    Dave

Re: if multiple conditions & Warinings....
by Eily (Monsignor) on Aug 21, 2013 at 18:49 UTC

    Below the text area when posting you could have seen some tips on how to write a post. <code> tags would have been useful there. UPG: Or Markup in the Monastery could be a useful read.

    For you problem ne compares two strings, which /^[+-]\d+$/ is not. It's a matching operation (it's actually m/EXPR/ but with / delimiters around the expression the m can be omitted), which you can use on a string with the binding operator =~ see Binding Operators. And you want to check that $VAR1 is a number before making a number comparison with it. So that's if ($VAR1 !~ /^[\-+]?\d+$/ || $VAR1 != 2).

    The next problem: - has a special meaning in a character range, so you have to escape it with \. Putting it in the first place is actually an exception to that, because it isn't ambiguous, but you can escape your - nonetheless, better safe than sorry.

    At last, since you seem to be discovering Perl, do turn on warnings and strict, don't wait until you find a bug.

    UPG: and maybe unless could make your code easier to read. And I don't see why you would include negative numbers if you're only looking for values different than 2. So you could actually write unless ($VAR1 =~ /^\+?2$/) { do some stuff }

      For you problem  ne compares two strings, which  /^[+-]\d+$/ is not.

      Actually, the problem with the  $VAR1 ne /^[+-]?\d+$/ expression in the OPed code is much more pernicious. In the absence of a  =~ binding operator,  // matches against the  $_ default scalar. If this scalar has a defined value, there will be no warning even if warnings are enabled. The  // match occurs in scalar context imposed by the  ne comparison operator. In scalar context,  // returns 1 (true) if there is a match and '' (empty string: false) if not. The  ne operator will stringize a 1 returned from a successful match. The  ne operator will stringize  $VAR1 and compare that against whatever resulted from the  // match. If  $VAR1 is defined, there will be no warning if warnings are enabled. Most of the values one can imagine  $VAR1 to contain will not (stringwise) equal either '1' or the empty string, thus setting the stage for very puzzling behavior.

      So even with strictures and warnings enabled, you might have been left with a devilish bug. Well, Perl is neither magical nor telepathic. There has to be some reason for the existence of the programmer, and that's why we earn the Big Buck$.

Re: if multiple conditions & Warinings....
by Laurent_R (Canon) on Aug 21, 2013 at 18:53 UTC

    Please use the formating tags to make your posts clearer. I have difficulties distinguishing your error or warning messages from your own question.

    Please also post the code snippet where you get this message. We can't guess without seeing your code. From what I can see in your post, it seems that $VAR1 is not numeric and you are comparing it numerically to 2 (!= is a numeric comparison), which seems to be the source of the error or warning. I can't say more, since I have no idea what $VAR1 is supposed to contain.