Permalink
Browse files

Avoid hitting ArgumentError for parsing integers and floats.

This patch is not quite perfect. There are cases that Integer and
Float handle that this does not, and the to_i and to_f methods
have the annoying tendency to ignore unparsable sections of the
string. We may just need to write a simple Ruby version of integer
and float parsing to use here. I'd be very surprised if it didn't
still balance out with regards to the exception-rescuing logic.
  • Loading branch information...
1 parent c37649b commit c1518790a153fa0557d651b2e70e31e3fa0cbce0 @headius committed Nov 2, 2012
Showing with 31 additions and 8 deletions.
  1. +31 −8 lib/psych/scalar_scanner.rb
@@ -86,19 +86,15 @@ def tokenize string
end
i
when FLOAT
- begin
- return Float(string.gsub(/[,_]/, ''))
- rescue ArgumentError
- end
+ float = parse_float(string)
+ return float if float
@string_cache[string] = true
string
else
if string.count('.') < 2
- begin
- return Integer(string.gsub(/[,_]/, ''))
- rescue ArgumentError
- end
+ integer = parse_integer(string)
+ return integer if integer
end
@string_cache[string] = true
@@ -107,6 +103,33 @@ def tokenize string
end
###
+ # Parse a string and attempt to return an integer, or nil if unparsable.
+ def parse_integer(string)
+ subbed_string = string.gsub(/[,_]/, '')
+ integer = subbed_string.to_i
+
+ # if result is zero, confirm there's no non-zero characters
+ return integer if integer != 0 || /^0+$/.match(subbed_string)
+
+ nil
+ end
+
+ ###
+ # Parse a string and attempt to return an integer, or nil if unparsable.
+ def parse_float(string)
+ # more than one . means it should not be a float
+ return nil if /\..*\./.match(string)
+
+ subbed_string = string.gsub(/[,_]/, '')
+ float = subbed_string.to_f
+
+ # if result is zero, confirm there's no non-zero characters
+ return float if float != 0.0 || /^0*\.0+$/.match(subbed_string)
+
+ nil
+ end
+
+ ###
# Parse and return a Time from +string+
def parse_time string
date, time = *(string.split(/[ tT]/, 2))

0 comments on commit c151879

Please sign in to comment.