From: see_signature@127.0.0.1 Date: 2001-05-02T09:10:08+09:00 Subject: [ruby-talk:14518] problems with String -> Numeric conversions Hi Experts, Ruby has a number of very useful functions which convert strings representing numbers into actual numbers: String#to_i String#to_f String#hex String#oct For some reason, which I cannot yet comprehend, these conversion functions provide NO ERROR HANDLING (no exceptions ever raised, no NaN ever returned). A string which does not correspond to any number is silently converted to zero. Therefore, if the outcome of a conversion is number zero, one cannot tell for sure whether this zero comes from a legitimate string representing number zero or from some guffy broken corrupted string: a = "0".to_i # -> 0 b = "garbage".to_i # -> 0 a == b # -> true The bugs which may result from this behavior can be very severe. A program can still run to completion but deliver incorrect results because the input integrity has been violated. I think that it will be useful if these conversion function perform some format validation. Since changes to core Ruby is a delicate and time consuming issue, here is a Ruby reimplementation of String#to_i and String#to_f which checks for correct format and raises an exception on error. Also, String#to_i distinguishes between decimal, octal and hexadecimal notations and parse these numbers accordingly. Any comments and feedback appreciated --Leo-- [ slonika AT yahoo DOT com ] #### RUBY CODE FOLLOWS #### # Conversion from a String to Numbers should raise an exception if the string has # an improper format. Strangely enough, Ruby's standard conversion functions do not # provide for any kind of error handling and return number '0' on failure. # Therefore, in Ruby one cannot possibly distinguish between these two cases: # "0".to_i # -> 0 # "not-a-number".to_i # -> 0 # The following code augments standard conversion functions String#to_i and # String#to_f with the error handling code so that an attempt to convert a # string not suited for numeric conversion will raise NumericError exception. class NumericError < RuntimeError end class String alias __std__to_i to_i if ! method_defined? :__std__to_i alias __std__to_f to_f if ! method_defined? :__std__to_f alias __std__hex hex if ! method_defined? :__std__hex alias __std__oct oct if ! method_defined? :__std__oct def to_i() case self when /^[-+]?0\d/ then __std__oct when /^[-+]?0x[a-f\d]/i then __std__hex when /^[-+]?\d/ then __std__to_i else raise NumericError, "Cannot convert string to Integer!" end end def to_f() case self when /^[-+]?\d/ then __std__to_f else raise NumericError, "Cannot convert string to Float!" end end end ################################################################################ #EOF