Мы уже упоминали директивы load и require. Важно понимать, что это не встроенные
предложения и не управляющие конструкции; на самом деле это методы.
Поэтому их можно вызывать, передавая переменные или выражения как параметры,
в том числе условно. Сравните с директивой #include в языках С и С++, которая
обрабатывается во время компиляции.
Код можно строить и интерпретировать по частям. В качестве несколько искусственного
примера рассмотрим приведенный ниже метод calculate и вызывающий
его код:
def calculate(opl, operator, op2)
string = opl.to_s + operator + op2.tb_s
# Предполагается, что operator - строка; построим длинную
# строку, состоящую из оператора и операндов.
eval(string) # Вычисляем и возвращаем значение.
end
@alpha = 25
@beta = 12
puts calculate(2, "+", 2) # Печатается 4
puts calculate(5, "*", "Salpha") # Печатается 125
puts calculate("@beta", »**", 3) # Печатается 1728
Вот та же идея, доведенная чуть ли не до абсурда: программа запрашивает у
пользователя имя метода и одну строку кода. Затем этот метод определяется и вызывается:
puts "Имя метода: "
meth_name = gets
puts "Строка кода: "
, code = gets
string = %[def #{meth_narae}\n #{code}\n end] # Строим строку,
eval(string) # Определяем метод,
eval(meth_name) # Вызываем метод.
Зачастую необходимо написать программу, которая могла бы работать на разных
платформах или при разных условиях, но при этом сохранить общий набор
исходных текстов. Для этого в языке С применяются директивы #if def, но в Ruby
все определения исполняются. Не существует такого понятия, как «этап компиляции
»; все конструкции динамические, а не статические. Поэтому для принятия
решения такого рода мы можем просто вычислить условие во время выполнения:
if platform == Windows
actionl
elsif platform == Linux
action2
else
default_action
end
Конечно, за такое кодирование приходится расплачиваться некоторым снижением
производительности, поскольку иногда условие вычисляется много раз. Но
рассмотрим следующий пример, который делает практически то же самое, однако
весь платформенно-зависимый код помещен в один метод, имя которого от платформы
не зависит:
if platform == Windows
def my_action
actionl
end
elsif platform == Linux
def my_action
action2
end
else
def my_action
default_action
end
end
Таким способом мы достигаем желаемого результата, но условие вычисляется
только один раз. Когда программа вызовет метод my_action, он уже будет правильно определен.
