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

Dear Monks,

What is the correct way to code the following?

   my $bigseqnum = int($seqnum) + 10000000 or write_line("non integer sequence number");

Sometimes $seqnum is an integer followed by some character data. In this case the leading number is used and trailing characters discarded.
The above works ok for this, it uses the leading number adds 10Mil to it and writes out the warning message.
BUT it is also writing the following to the consul:
   Argument "\x{31}\x{30}..." isn't numeric in int at ppm.pl line 149.

Please, what is the right way to code the statement, and how can we avoid the consul warning message.

Thanks for your time!!!!

Replies are listed 'Best First'.
Re: Style and warnings
by jethro (Monsignor) on Aug 18, 2009 at 15:08 UTC
    my ($num)= $seqnum=~/^(\d+)/; my $bigseqnum = $num + 10000000 ...

    This naturally only works if the number in $seqnum always conforms to that regex (for example no negative number) and there are no spaces etc. before the number. Otherwise the regex has to be adapted to work in all those cases

    The other possibility is to turn of warnings at that point:

    no warnings; my $bigseqnum = int($seqnum) + 10000000 ... use warnings;
      I generally prefer do blocks for making it really, really obvious that I'm doing silly things, and what the scope of that silliness actually is:
      my $bigseqnum = do { no warnings; int($seqnum) + 10000000 };
      Or, to be more explicit, no warnings 'numeric';
      You know that this still may give the warning?

      An example where you still can get the warning: "๑๒๓" ("123" in Thai digits). \d is such a poor substitute for [0-9].

        Ah, the pitfalls of UTF. Did not know that and don't like it at all, I used \d as shorthand for 0-9 a lot. My old camel book still says "\d - A digit, same as [0-9]"

        I think I would have prefered a new character for this class to a break of backwards compatibility. The other solution that the internal number conversion also recognizes thai and other numbers would be even better theoretically, but that may not be easy with UTF

      my ($num)= $seqnum=~/^(\d+)/;
      This would extract the first string of digits inside the string $seqnum. I'm not sure whether this is what the OP wanted. Giving the call to the write-function in the posting, I rather think the OP would like to catch those cases where the string does not evaluate to an integral number. I think one portable solution would be

      use Scalar::Util qw(looks_like_number); if(looks_like_number($seqnum) && int($seqnum)==$seqnum) { # $seqnum is arithmetically an integral number }

      -- 
      Ronald Fischer <ynnor@mm.st>
Re: Style and warnings
by rovf (Priest) on Aug 18, 2009 at 14:59 UTC
    Can you give an example for $seqnum, where you get the warning?
    $bigseqnum = int($seqnum) + 10000000 or write_line("non integer sequence number")
    You are aware that write_line will be called if $seqnum == -1000000 ?

    -- 
    Ronald Fischer <ynnor@mm.st>
      Thanks very much for the help!!!
      The sequence number is always a positive integer but sometimes with trailing junk.
      like: 23543 or 34756P
Re: Style and warnings
by BioLion (Curate) on Aug 18, 2009 at 15:36 UTC

    It is just a personal preference, but i would make a little sub that would package away the addition, and do the input checking (i.e. remove any non-digits, warn if the number is -1000_000, or any other of the situations pointed out) and provide helpful errors if anything is bad.

    use warnings; ## or die! use strict; ## seriously - don't anger the gods use diagnostics; ## but if you do, make them tell you why (patiently) +... if (my $big_int = big_int('101_dalmations') ){ ... it was OK so go ahead and play ... } else { ... no need for this bit, error messages already generated! ... ... maybe you want to do something else though? ... } ### SUBS ### sub big_int{ my $input = shift; ## check for any source of errors if ( $input =~ /\D/ ){ ## non-digits - argh! warn "$input contains non digits\n"; return 0; } elsif (... something else ...){ ... } return ($input + 1000_000); }

    It just means that what you are actually trying to achieve (make a big int) remains clear, while also handling the errors nicely if they don't conform etc...

    Just MHO though...

    Just a something something...
      There are perfectly valid numbers that Perl can deal with, even without warnings, which still contain non-digit characters. 1.3 comes to mind. And so do -5 and 3e5.

      Furthermore, there are strings containing no \D characters, but which Perl cannot treat as numbers. "๑๒๓" for instance.

      If you wish to find out whether a string looks like a number, use Scalar::Util::looks_like_number. Don't use simplistic regexes.

        Just making an example. OP would have to make specific checks based on their input.

        You never know, maybe they are only dealing with integers, possibly joined with types of dog, in which case my example was perfect.

        Just a something something...
      Thanks all very much for the great answers!!!
      A subroutine to allow for using the leading number and logging a warning with blocking the consul log seems best for this case.

      Thanks!!