On Tue, Jan 19, 2010 at 5:40 AM, Shot (Piotr Szotkowski) <shot / hot.pl> wrote:
> Jes Gabriel y Gal:
>
>> On Tue, Jan 19, 2010 at 11:13 AM, Phillip Curry <philfo / gmail.com> wrote:
>
>>> Is there a nice way to convert a string to an integer if it is in
>>> fact an integer, and to return nil or even an error if it's not?
>
>> Try this:
>
>> irb(main):002:0> Integer("12")
>> => 12
>> irb(main):003:0> Integer("fdfdf")
>> ArgumentError: invalid value for Integer: "fdfdf"
>> from (irb):3:in `Integer'
>> from (irb):3
>> from :0
>> irb(main):005:0> Integer("12ijk")
>> ArgumentError: invalid value for Integer: "12ijk"
>> from (irb):5:in `Integer'
>> from (irb):5
>> from :0
>
> nd if you rather get nil, you can try rescuing the exception inline:
>
>>> Integer('12')
> => 12
>>> Integer('fdfdf') rescue nil
> => nil
>>> Integer('12ijk') rescue nil
> => nil

However you need to be aware of issues like this:

ruby-1.8.6-p383 > Integer("0xFF")
 => 255
ruby-1.8.6-p383 > Integer("033")
 => 27
ruby-1.8.6-p383 > Integer("082")
ArgumentError: invalid value for Integer: "082"
	from (irb):5:in `Integer'
	from (irb):5

It should be obvious, but what's happening is that the Kernel#Integer
method treats an initial 0 as indication of a radix, with 0x giving
base 16, 0b base 2, and 0 alone base 8.

If this is an issue, then I'd recommend validating arbitrary strings
using a regex before conversion to an integer. Something like:

def safe_string_to_int(string)
     if /^\d+$/.match(string)
          string.to_i(10)
     else
          nil
     end
end

There are probably better ways to write this, but I think that this
form may be clearer for a newbie to understand.

-- 
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale