У техники работы с eval есть свои «причуды». Например, будьте осторожны, вставляя управляющие последовательности, скажем .

2.23. Разбор данных, разделенных запятыми

Данные, разделенные запятыми, часто встречаются при программировании. Это в некотором роде «наибольший общий делитель» всех форматов обмена данными. Например, так передаются данные между несовместимыми СУБД или приложениями, которые не поддерживают никакого другого общего формата.

Будем предполагать, что данные представляют собой строки и числа, а все строки заключены в кавычки. Еще предположим, что все символы должным образом экранированы (например, запятые и кавычки внутри строки).

Задача оказывается простой, поскольку такой формат данных подозрительно напоминает встроенные в Ruby массивы данных разных типов. Достаточно заключить все выражение в квадратные скобки, чтобы получить массив.

string = gets.chop!

#Предположим, что прочитана такая строка:

#'Doe, John', 35, 225, '5'10'', '555-0123'

data = eval('[' + string + ']') # Преобразовать в массив.

data.each {|x| puts 'Значение = #{x}'}

Этот код выводит такой результат:

Значение = Doe, John

Значение =35

Значение =225

Значение = 5' 10'

Значение = 555-0123

Более общее решение дает стандартная библиотека CSV. Есть также усовершенствованный инструмент под названием FasterCSV. Поищите его в сети, он не входит в стандартный дистрибутив Ruby.

2.24. Преобразование строки в число (десятичное или иное)

Есть два основных способа преобразовать строку в число: методы Integer и Float модуля Kernel и методы to_i и to_f класса String. (Имена, начинающиеся с прописной буквы, например Integer, обычно резервируются для специальных функций преобразования.)

Простой случай тривиален, следующие два предложения эквивалентны:

x = '123'.to_i     # 123

y = Integer('123') # 123

Но если в строке хранится не число, то поведение этих методов различается:

x = junk'.to_i      # Молча возвращает 0.

y = Integer('junk') # Ошибка.

Метод to_i прекращает преобразование, как только встречает первый символ, не являющийся цифрой, а метод Integer в этом случае возбуждает исключение:

x = '123junk'.to_i     # 123

y = Integer('123junk') # Ошибка.

Оба метода допускают наличие пропусков в начале и в конце строки:

x = ' 123 '.to_i     # 123

y = Integer(' 123 ') # 123

Преобразование строки в число с плавающей точкой работает аналогично:

x = '3.1416'.to_f  # 3.1416

y = Float('2.718') # 2.718

Оба метода понимают научную нотацию:

x = Float('6.02е23')   # 6.02е23

y = '2.9979246е5'.to_f # 299792.46

Методы to_i и Integer также по-разному относятся к системе счисления. По умолчанию, естественно, подразумевается система по основанию 10, но другие тоже допускаются (это справедливо и для чисел с плавающей точкой).

Говоря о преобразовании из одной системы счисления в другую, мы всегда имеем в виду строки. Ведь целое число неизменно хранится в двоичном виде.

Следовательно, преобразование системы счисления — это всегда преобразование одной строки в другую. Здесь мы рассмотрим преобразование из строки (обратное преобразование рассматривается в разделах 5.18 и 5.5).

Числу в тексте программы может предшествовать префикс, обозначающий основание системы счисления. Префикс 0b обозначает двоичное число, 0 — восьмеричное, а 0x — шестнадцатеричное.

Метод Integer такие префиксы понимает, а метод to_i — нет:

x = Integer('0b111') # Двоичное - возвращает 7.

y = Integer('0111')  # Восьмеричное - возвращает 73.

z = Integer('0x111') # Шестнадцатеричное - возвращает 291.

x = '0b111'.to_i     # 0

y = '0111'.to_i      # 0

z = '0x111'.to_i     # 0

Однако у метода to_i есть необязательный второй параметр для указания основания. Обычно применяют только четыре основания: 2, 8, 10 (по умолчанию) и 16. Впрочем, префиксы не распознаются даже при определении основания.

x = '111'.to_i(2)  # 7

y = '111'.to_i(8)  # Восьмеричное - возвращает 73.

z = '111'.to_i(16) # Шестнадцатеричное - возвращает 291.

x = '0b111'.to_i # 0

y = '0111'.to_i  # 0

z = '0x111'.to_i # 0

Из-за «стандартного» поведения этих методов цифры, недопустимые при данном основании, обрабатываются по-разному:

x = '12389'.to_i(8) # 123 (8 игнорируется).

y = Integer('012389') # Ошибка (8 недопустима).

Хотя полезность этого и сомнительна, метод to_i понимает основания вплоть до 36, когда в представлении числа допустимы все буквы латинского алфавита. (Возможно, это напомнило вам о base64-кодировании; дополнительную информацию по этому поводу вы найдете в разделе 2.37.)

x = '123'.to_i(5) # 66

y = 'ruby'.to_i (36) # 1299022

Для преобразования символьной строки в число можно также воспользоваться методом scanf из стандартной библиотеки, которая добавляет его в модуль Kernel, а также классы IO и String:

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату