Введите температуру и шкалу (С or F): 98.6 F
37.0 градусов С
Введите температуру и шкалу (С or F): 100 С
212.0 градусов F
Введите температуру и шкалу (С or F):
92 G Необходимо задать С или F.
Введите температуру и шкалу (С or F): junk F
junk недопустимое число.
Теперь рассмотрим, как эта программа работает. Все начинается с предложения print
, которое есть не что иное, как вызов метода print
из модуля Kernel
. Данный метод выполняет печать на стандартный вывод. Это самый простой способ оставить курсор в конце строки.
Далее мы вызываем метод gets
(прочитать строку из стандартного ввода) и присваиваем полученное значение переменной str
. Для удаления хвостового символа новой строки вызывается метод chomp!
.
Обратите внимание, что print
и gets
, которые выглядят как «свободные» функции, на самом деле являются методами класса Object
(который, вероятно, наследует Kernel
). Точно так же chomp!
— метод, вызываемый от имени объекта str
. При вызовах методов в Ruby обычно можно опускать скобки: print "foo"
и print("foo")
— одно и то же.
В переменной str
хранится символьная строка, но могли бы храниться данные любого другого типа. В Ruby данные имеют тип, а переменные - нет. Переменная начинает существовать, как только интерпретатор распознает присваивание ей; никаких предварительных объявлений не существует.
Метод exit
завершает программу. В той же строке мы видим управляющую конструкцию, которая называется «модификатор if
». Он аналогичен предложению if
, существующему в большинстве языков, только располагается после действия. Для модификатора if
нельзя задать ветвь else
, и он не требует закрытия. Что касается условия, мы проверяем две вещи: имеет ли переменная str
значение (то есть не равна nil
) и не является ли она пустой строкой. Если встретится конец файла, то будет истинно первое условие; если же пользователь нажмет клавишу Enter, не введя никаких данных, — второе.
Это предложение можно было бы записать и по-другому:
exit if not str or not str[0]
Эти проверки работают потому, что переменная может иметь значение nil
, а nil
в Ruby в логическом контексте вычисляется как «ложно». На самом деле как «ложно» вычисляются nil
и false
, а все остальное — как «истинно». Это означает, кстати, что пустая строка ""
и число 0 — не «ложно».
В следующем предложении над строкой выполняется операция chomp!
(для удаления хвостового символа новой строки). Восклицательный знак в конце предупреждает, что операция изменяет значение самой строки, а не возвращает новую. Восклицательный знак применяется во многих подобных ситуациях как напоминание программисту о том, что у метода есть побочное действие или что он более «опасен», чем аналогичный метод без восклицательного знака. Так, метод chomp
возвращает такой же результат, но не модифицирует значение строки, для которой вызван.
В следующем предложении мы видим пример множественного присваивания. Метод split
разбивает строку на куски по пробелам и возвращает массив. Двум переменным в левой части оператора присваиваются значения первых двух элементов массива в правой части.
В следующем предложении if
с помощью простого регулярного выражения выясняется, введено ли допустимое число. Если строка не соответствует образцу, который состоит из необязательного знака «минус» и одной или более цифр, то число считается недопустимым и программа завершается. Отметим, что предложение if оканчивается ключевым словом end
. Хотя в данном случае это не нужно. Мы могли бы включить перед end
ветвь else
. Ключевое слово then
необязательно; в этой книге мы стараемся не употреблять его.
Метод to_f
преобразует строку в число с плавающей точкой. Это число записывается в ту же переменную temp
, в которой раньше хранилась строка.
Предложение case
выбирает одну из трех ветвей: пользователь указал С
, F
или какое-то другое значение в качестве шкалы. В первых двух случаях выполняется вычисление, в третьем мы печатаем сообщение об ошибке и выходим.
Кстати, предложение case
в Ruby позволяет гораздо больше, чем показано в примере. Нет никаких ограничений на типы данных, а все выражения могут быть произвольно сложными, в том числе диапазонами или регулярными выражениями.