sub valid_number { # See if a string is a valid number. WJS Apr 99 # Idea is to turn warnings on, force a numeric calculation, trap # any resulting warning message, and see if it's appropriate. # Because it's only a warning, eval does not set $@ as it does for # worse errors. Therefore, the fooling with signals... # Of course this breaks if the message changes. Much better would # be to have a perl-callable strtod function... # The perl manual says that numbers match /[+-]\d*\.?\d*E[+-]\d+/ # (when it was talking about library module BigFloat). However, that # description clearly doesn't reflect the optional portions of numbers... local ($numeric_flag) = 1; my ($old_val_warn) = $^W; $^W = 1; # Turn on warnings # Used to have sub test $_[0] (the warning message) to see if it was # an "Argument .* not numeric" message. Now think that if the eval gets # any kind of warning, there must be a problem with the putative number, # so just decide it's not a number. Presumably if there were # a numeric warning (overflow? is this a fatal?), the this technique # would be incorrect. If we know that numeric warnings have their # own signal, presumably we could trap that, too (and we'd get it before # __WARN__ or __DIE__?) local $SIG{__WARN__} = sub { $numeric_flag = 0; }; eval '$_[0] + 1'; # Anything that does arithmetic $old_val_warn || ($^W = 0); # Reset warnings if appropriate $SIG{__WARN__} = 'DEFAULT'; # Return signal to normal behavior return $numeric_flag; } 1;