I'm trying to catch the difference between a numeric string vs. an arbitrary string:
'0'.to_f
#=> 0.0
'hello'.to_f
#=> 0.0
Both of the above return a Float
. How do I catch the difference if the user inputs the actual value '0'
or if the user inputs the value 'hello'
?
I am trying to create a simple Celsius to Fahrenheit calculator. If the user inputs "hello"
the program should output Please type in a number:
but if the user types in 0
then the program should output the correct Fahrenheit calculation.
Use this:
number = Float( string_to_convert ) rescue nil
if number.nil?
puts "#{string_to_convert} is not a number"
else
# DO the conversion
end
This will use a sensible set of rules for converting String values into Floats, supporting negative numbers, scientific notation, whilst not requiring you write a regular expression to try and capture all the valid ways of expressing floating point numbers in Ruby.
The rescue
is required to catch the error from a failed conversion.
Potentially better Ruby code for your particular purpose (and combining design from Tamer's answer with feedback from Stefan in comments):
begin
number = Float( string_to_convert )
rescue ArgumentError
puts "'#{string_to_convert}' is not a number"
else
# Do the conversion, using number variable
end
However, if the program flow is more complicated than input-or-bust-then-repeat, I still find the one-liner can be useful - provided of course you either raise an error later or can deal with missing values because the conversion to a Float failed.
You could use a regular expression like:
/
\A # anchor on start of a string, so there there is nothing more than float allowed
\-? # optional minus
\d+ # non-empty row of digits
(
\. # dot
\d+ # another row of digits
)? # ? means both of the above are optional
\z # anchor on end of a string, so there there is nothing more than float allowed
/x
single line version: /\A\-?\d+(\.\d+)?\z/
In typical use-case, Float( )
might be better, but using a regex separates you from Ruby's definition of Float literal, that can come handy if i.e. you want to allow a comma as decimal mark, or thousand separator (Ruby will only allow .
and _
respectively). Regex match will also just return true
or false
, that can be useful if you want to avoid exception handling - ArgumentError
thrown by Float( )
on fail is pretty generic, so it might get thrown by other nearby method call, and thus can get difficult to handle properly, or just make your code ugly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With