Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

(tye)Re: Integer detection concept

by tye (Sage)
on May 15, 2001 at 00:40 UTC ( [id://80342]=note: print w/replies, xml ) Need Help??


in reply to Integer detection concept

Well, I can think of quite a few meanings of "is an integer".

  1. Fits in a Perl UV:
    sub isUV { my( $i )= @_; return isIntVal($i) && $i == (0|$i); }
  2. Fits in a Perl IV (no test provided)
  3. Fits in a Perl NV but has no fractional part:
    sub isNVint { my( $i )= @_; return isIntVal($i) && $i == int($i); }
  4. Is the (string) representation of an integer that may not fit into (1), (2), or (3):
    sub isInt { my( $i )= @_; return $i =~ /^-?\d+\z/; }
  5. A scalar that will result in (1), (2), or (3) w/o warning when used in a "numeric context":
    sub isIntVal { my( $i )= @_; return $i =~ /^\s*[-+]?\d+\s*$/; }
    But (update) that doesn't cover "1.2e4", for example, so you can also use (updated):
    sub isIntVal2 { my( $i )= @_; my $warn= 0; { local( $^W )= 1; # my $warn= 0; local( $SIG{__WARN__} )= sub { $warn++ }; $i= 0+$i; } return ! $warn && int($i) == $i; }
  6. A string that will result in literal (1), (2), or (3) w/o warning when used in Perl code (for example, with eval). This one has to allow for _ in the middle, "0x" or "0b" at the start, etc.
And, in particular, (4) has plenty of room for changes based on what you think should be allowed. And my test for (3) doesn't account for numbers that don't accurately fit in an NV.

I really think that the best solution involves making the looks_like_number() C subroutine that Perl itself uses available to scripts.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: (tye)Re: Integer detection concept
by relax99 (Monk) on Dec 13, 2002 at 15:41 UTC

    No. 5 looks like a pretty cool solution to the problem. There's one thing with this code though that I can't figure out. It looks to me that you're using a closure, but it doesn't work. When I try to run this code Perl complains: Global symbol "$warn" requires explicit package name

    I could only make this work by removing the outer { }. Does anyone know why this closure doesn't work?

      Sorry, my bad. I fixed the code and left the original broken bit in, just commented out.

              - tye
      That's because it's not a closure. Closures are subroutines that maintain the lexical state around them outside the scope of that lexical state. There's no subroutine involved.

      The reason for the extra brackets is to provide a scope for the local $^W = 1;.

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

        Look a bit more closely. There is an anonymous sub there which gets called by the perl runtime in event of a warning.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2024-04-25 19:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found