При чтении данных из файла или другого внешнего ресурса данные всегда приходят в Ruby как объекты String (Строка).

Если мы хотим использовать их как числа, сначала их нужно сконвертировать в числа.

Но в какие и как?

Объект String в Ruby имеет несколько методов конверации в число.

  • to_i сконвертирует String в Integer.
  • to_f сконвертирует String во Float (с плавающей точкой)
  • to_r сконвертирует String в Rational number (рациональное число).
  • to_c сконвертирует String в Complex number (комплексное число).

Конкатенация

Если для двух числовых значений, которые на самом деле объекты String (из-за обрамляющих кавычек), использовать оператор +, то он будет работать как конкатенация.

a = "2"
b = "3"
puts a+b  # 23

no implicit conversion of Fixnum into String (TypeError)

Если одно из значений это объект String, а другое - число (без кавычек), и мы попробуем сложить их друг с другом, как в примере:

puts "2"+3 

мы получим исключение: no implicit conversion of Fixnum into String (TypeError)

String, которые выглядят как integer

String, содержащие целое число (integer) могут быть сконвертированы в Integer, Float, Rational number, или Complex number:

puts a.to_i # 2
puts a.to_f # 2.0
puts a.to_r # 2/1
puts a.to_c # 2+0i

Как задать основание: конвертация двоичных, восьмеричных, шестнадцатеричных значений в десятичные

По умолчанию to_i предполагает, что наш объект String представлен в десятичной системе (основание 10), но что если вы хотите это изменить?

Что если вы хотите рассматривать String как двоичное число, восьмеричное или шестнадцатеричное? Тогда нужно просто передать аргумент base= с подходящим числом в метод to_i:

puts "11".to_i            # 11
puts "11".to_i(base=2)    # 3
puts "11".to_i(base=16)   # 17

Конечно шестнадцатеричные числа могут также содержать символы a-f. Функция to_i умеет с ними обращаться.

puts "aB".to_i(base=16)   # 171

Возникает вопрос, что случится, если мы используем to_i без указания основания для строки с шестнадцатеричным числом, или с основанием, которое не предусматривает таких символов? Тогда просто вернется 0 (без какой-либо ошибки).

puts "aB".to_i            # 0
puts "9".to_i(base=8)     # 0

Это подводит нас к вопросу: Что случится, если не все символы могут быть сконвертированы в число? Ответ прост. to_i сконвертирует все 'digits' от начала до того места, где уже не будет понятно, что делать. Оставшаяся часть строки будет отброшена. Даже если там есть еще понимаемые значения.

puts "2x3".to_i           # 2
puts "2 3".to_i           # 2

Конвертация в число с плавающей точкой или рациональное число

Мы можем использовать остальные методы для конвертации во Floating point (число с плавающей точкой), Rational number (рациональное число), и даже в Complex number (комплексное число): Некоторые из них понимают точку в десятичной дроби в String

c = "14.6"
puts c.to_i    # 14
puts c.to_f    # 14.6
puts c.to_r    # 73/5
puts c.to_c    # 14.6+0i

Некоторые даже понимают символ e, обозначающий экспоненту в String:

e = "2.3e4x5"
puts e         # 2.3e4x5
puts e.to_i    # 2
puts e.to_f    # 23000.0
puts e.to_r    # 23000/1
puts e.to_c    # 23000.0+0i

Полный пример

examples/ruby/string_to_number.rb


a = "2"
b = "3"
puts a+b  # 23
puts '-------'

# puts "2"+3   # no implicit conversion of Fixnum into String (TypeError)

puts a.to_i # 2
puts a.to_f # 2.0
puts a.to_r # 2/1
puts a.to_c # 2+0i
puts '-------'

puts "11".to_i            # 11
puts "11".to_i(base=2)    # 3
puts "11".to_i(base=8)    # 9
puts "11".to_i(base=16)   # 17
puts '-------'

puts "aB".to_i(base=16)   # 171
puts "aB".to_i            # 0
puts "9".to_i(base=8)     # 0
puts '-------'

puts "2x3".to_i           # 2
puts "2 3".to_i           # 2
puts '-------'

c = "14.6"
puts c.to_i    # 14
puts c.to_f    # 14.6
puts c.to_r    # 73/5
puts c.to_c    # 14.6+0i
puts '-------'


e = "2.3e4x5"
puts e         # 2.3e4x5
puts e.to_i    # 2
puts e.to_f    # 23000.0
puts e.to_r    # 23000/1
puts e.to_c    # 23000.0+0i
puts '-------'