I agree with syphilis here (update: and haukex here) that Scalar::Util::looks_like_number() looks like a better solution. One problem with this is that it's dependent upon the state of warnings in the enclosing scope:

c:\@Work\Perl\monks>perl -le "use strict; use warnings; ;; no warnings 'numeric'; print 'numeric warning DISabled'; ;; print q{'abc' }, isNumber('abc'); print q{'123' }, isNumber('123'); print q{123 }, isNumber(123); ;; sub isNumber { @_ or return 0; my $N = shift; defined $N or return 0; my $R = 1; { local $SIG{__WARN__} = sub { $R = 0; }; $N = int($N); } return $R; } " numeric warning DISabled 'abc' 1 '123' 1 123 1
A fix (if you're wedded to isNumber()) might be something like:
c:\@Work\Perl\monks>perl -le "use strict; use warnings; ;; no warnings 'numeric'; print 'numeric warning DISabled'; ;; print q{'abc' }, isNumber('abc'); print q{'123' }, isNumber('123'); print q{123 }, isNumber(123); print q{undef }, isNumber(undef); print q{() }, isNumber(); ;; sub isNumber { my $numeric = 1; use warnings 'numeric'; local $SIG{__WARN__} = sub { $numeric = 0; }; my $x = int $_[0]; return $numeric; } " numeric warning DISabled 'abc' 0 '123' 1 123 1 undef 0 () 0
A test plan:
c:\@Work\Perl\monks>perl -le "use warnings; use strict; ;; use Test::More 'no_plan'; use Test::NoWarnings; ;; note qq{perl version $]}; ;; no warnings 'numeric'; note 'numeric warnings DISabled'; ;; note 'should all return 0'; ok isNumber() == 0, q{isNumber() empty argument list}; ok isNumber('') == 0, q{isNumber('') empty string}; ok isNumber('x') == 0, q{isNumber('x'}; ok isNumber('abc') == 0, q{isNumber('abc'}; ok isNumber('x1') == 0, q{isNumber('x1'}; ok isNumber('1x') == 0, q{isNumber('1x'}; note 'should all return 1'; ok isNumber(0) == 1, q{isNumber(0)}; ok isNumber(0.) == 1, q{isNumber(0.)}; ok isNumber(.0) == 1, q{isNumber(.0)}; ok isNumber(0.0) == 1, q{isNumber(0.0)}; ok isNumber(1) == 1, q{isNumber(1)}; ok isNumber(1.) == 1, q{isNumber(1.)}; ok isNumber(.1) == 1, q{isNumber(.1)}; ok isNumber(1.0) == 1, q{isNumber(1.0)}; ok isNumber(0.1) == 1, q{isNumber(0.1)}; ok isNumber(1.1) == 1, q{isNumber(0.1)}; ok isNumber('0') == 1, q{isNumber('0')}; ok isNumber('0.') == 1, q{isNumber('0.')}; ok isNumber('.0') == 1, q{isNumber('.0')}; ok isNumber('0.0') == 1, q{isNumber('0.0')}; ok isNumber('1') == 1, q{isNumber('1')}; ok isNumber('1.') == 1, q{isNumber('1.')}; ok isNumber('.1') == 1, q{isNumber('.1')}; ok isNumber('1.0') == 1, q{isNumber('1.0')}; ok isNumber('0.1') == 1, q{isNumber('0.1')}; ok isNumber('1.1') == 1, q{isNumber('1.1')}; ok isNumber(.0001) == 1, q{isNumber(.0001)}; ok isNumber('.0001') == 1, q{isNumber('.0001')}; ok isNumber(1234.0001) == 1, q{isNumber(1234.0001)}; ok isNumber('1234.0001') == 1, q{isNumber('1234.0001')}; ok isNumber(1234e12) == 1, q{isNumber(1234e12)}; ok isNumber('1234e12') == 1, q{isNumber('1234e12')}; ;; done_testing; exit; ;; sub isNumber { my $numeric = 1; use warnings 'numeric'; local $SIG{__WARN__} = sub { $numeric = 0; }; my $x = int $_[0]; return $numeric; } " # perl version 5.008009 # numeric warnings DISabled # should all return 0 ok 1 - isNumber() empty argument list ok 2 - isNumber('') empty string ok 3 - isNumber('x' ok 4 - isNumber('abc' ok 5 - isNumber('x1' ok 6 - isNumber('1x' # should all return 1 ok 7 - isNumber(0) ok 8 - isNumber(0.) ok 9 - isNumber(.0) ok 10 - isNumber(0.0) ok 11 - isNumber(1) ok 12 - isNumber(1.) ok 13 - isNumber(.1) ok 14 - isNumber(1.0) ok 15 - isNumber(0.1) ok 16 - isNumber(0.1) ok 17 - isNumber('0') ok 18 - isNumber('0.') ok 19 - isNumber('.0') ok 20 - isNumber('0.0') ok 21 - isNumber('1') ok 22 - isNumber('1.') ok 23 - isNumber('.1') ok 24 - isNumber('1.0') ok 25 - isNumber('0.1') ok 26 - isNumber('1.1') ok 27 - isNumber(.0001) ok 28 - isNumber('.0001') ok 29 - isNumber(1234.0001) ok 30 - isNumber('1234.0001') ok 31 - isNumber(1234e12) ok 32 - isNumber('1234e12') 1..32 ok 33 - no warnings 1..33
More test cases would be wise: there are no negatives, +0, +1, '+0', '+1', +123e+45, etc.


Give a man a fish:  <%-{-{-{-<


In reply to Re^3: How to capture the "isn't numeric" warning? by AnomalousMonk
in thread How to capture the "isn't numeric" warning? by harangzsolt33

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.