views:

457

answers:

3

I am trying to decide if a string is a number in Ruby. This is my code

whatAmI = "32.3a22"
puts "This is always false " + String(whatAmI.is_a?(Fixnum));
isNum = false;
begin
  Float(whatAmI)
  isNum = true;
rescue Exception => e
  puts "What does Ruby say? " + e
  isNum = false;
end
puts isNum

I realize that I can do it with a RegEx, but is there any standard way to do it that I'm missing? I've seen a can_convert? method, but I don't seem to have it.

Is there a way to add a can_convert? method to all Strings? I understand that it's possible in Ruby. I also understand that this may be totally unecessary...

Edit The to_f methods do not work, as they never throw an Exception but rather just return 0 if it doesn't work out.

+3  A: 

I don't know about the can_convert method, but generally a class will define methods like to_s, to_i, to_hash and so on. These methods return a different representation of the object, for example, a to_s method will return a string representation of an object.

As for the actual converting, I'm sure someone else can answer that better than me.

On another note, if you're wondering if you can add a method to all strings, you can. Just open up the String class and add it!

class String
  def can_convert?
    ...
  end
end

Edit: Strings containing exponential notation are supported by to_f.

>> "6.02e23".to_f
=> 6.02e+23
dylanfm
I agree on the to_i method. There is a to_f method, too.The latter 'note', about String extension, is called Monkey Patching, and is strongly advised against!
xtofl
Yeah, I thought there was another way to modify String... but it might be just a single instance of String that can be modified.
Yar
You can add a singleton method to String or a string object if you're after that.
dylanfm
Without modifying the String class file itself?
Yar
Yea, without modifying it.
dylanfm
Cool... like this, I assume: http://ola-bini.blogspot.com/2006/09/ruby-singleton-class.html
Yar
That looks right.
dylanfm
+4  A: 

You've got the right idea. It can be done a little more compactly, though:

isNum = Float(whatAmI) rescue nil

Inlining "rescue" is great fun. Parenthesize the part you're rescuing if you put it in the middle of more stuff, like:

if (isNum = Float(whatAmI) rescue nil) && isNum > 20
  ...
glenn mcdonald
nice! that's what I needed.
Yar
+3  A: 

This might sound overly critical, but based on your description, you're almost certainly doing something "wrong"... Why would you need to check whether a String is a valid representation of a Float but not actually convert the String?

This is just a hunch, but it may be useful to describe what you're trying to accomplish. There's probably a "better" way.

For example, you might want to insert the String into a database and put together an sql statement using string concatenation. It would be preferable to convert to a Float and use prepared statements.

If you just need to inspect the "shape" of the string, it would be preferable to use a regular expression, because, as dylan pointed out, a Float can be represented in any number of ways that may or may not be appropriate.

You may also have to deal with international input, in Europe, a comma is used instead of a period as decimal seperator, yet Ruby Floats have to use the (.).

The question grew out of something simple which I'll do with a RegEx, just to check if the String is an int (meaning an ID) or not (an action, like "login"). But then I got curious...
Yar
Thanks for the answer. I think you're right about the regex, and you're definitely right that this is probably not necessary.
Yar