Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re^3: How to capture the "isn't numeric" warning?

by haukex (Archbishop)
on Jun 15, 2019 at 10:01 UTC ( [id://11101392]=note: print w/replies, xml ) Need Help??


in reply to Re^2: How to capture the "isn't numeric" warning?
in thread How to capture the "isn't numeric" warning?

That's exactly what I wanted to know. So, what do you think of my sub?

Sorry, but I don't think it's a good idea. For one, the signal handler will fire on any warning. Scalar::Util's looks_like_number (a core module) calls the internal Perl function that checks if a string looks like a number, so this is just a really convoluted way of calling that function. In your OP, you said "Is there a faster way to test if a variable is a number?", and this is definitely a much slower way to do so - in fact, roughly 38 times slower! As numerous people have said, just use looks_like_number.

use warnings; use strict; use Benchmark qw/cmpthese/; use Scalar::Util qw/looks_like_number/; 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; } cmpthese(-2, { isNumber => sub { isNumber("123") or die; isNumber("-5e7") or die; isNumber("abc") and die; isNumber("") and die; }, looks_like_number => sub { looks_like_number("123") or die; looks_like_number("-5e7") or die; looks_like_number("abc") and die; looks_like_number("") and die; } }); __END__ Rate isNumber looks_like_number isNumber 153840/s -- -97% looks_like_number 5991731/s 3795% --

Replies are listed 'Best First'.
Re^4: How to capture the "isn't numeric" warning?
by syphilis (Archbishop) on Jun 15, 2019 at 13:33 UTC
    For one, the signal handler will fire on any warning.

    Yes, the same thought occurred to me ... but then I couldn't come up with an argument that could be passed to isNumeric() && elicit a warning other than the "isn't numeric" one.
    Is there such an argument ?

    Cheers,
    Rob

      You could get it from an object that overloads numification (0+) or int, and the sub handling the overload warns.

      One could argue that isNumber gives the better result in that situation.

        You could get it from an object that overloads numification (0+) or int

        Yes, that would do it.

        I did find a case where Scalar::Util::looks_like_number and the OP's isNumber return a different value for the same argument, but it had nothing to do with emission of warnings.

        For the arguments Math::MPFR->new(), Math::MPFR->new('nan') and Math::MPFR->new('inf'), Scalar::Util::looks_like_number will return FALSE, while isNumber will return TRUE.

        But this is probably the fault of Math::MPFR, which stringifies all values the same way as the mpfr library.
        And those 3 expressions therefore get stringified as "@NaN@", "@NaN@" and "@Inf@" (respectively).

        Math::MPFR probably should fix this by doing a s/@//g on the string prior to returning it. (And I'll attend to that.)

        I'll also mention that there's a perl API subroutine also named looks_like_number, but it doesn't look for any magic and therefore returns FALSE for most objects.
        Actually, I don't know of any cases where it will return TRUE for an object ... but I'm wary of asserting that such a case doesn't exist, or couldn't be constructed ...

        Cheers,
        Rob

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (5)
As of 2024-04-23 07:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found