Когда локальная переменная становится доступной?
На самом деле этот вопрос лучше задать так: "На какой стадии Ruby вычисляет, что нечто является переменной?". Проблема возникает по той причине, что простое выражение "а" может быть и переменной, и вызовом метода без параметров. Чтобы определить, что такое "а", Ruby ищет операции присваивания переменной с таким именем до текущего использования "а" . Если присваивание имело место, это переменная, иначе это имя метод. Несколько патологический пример этого механизма продемонстрирован ниже кодом, присланным
Клеменсом Хинцом (Clemens Hintze):
def a
print "Function 'a' called
"
99
end
for i in 1..2
if i == 2
print "a=", a, "
"
else
a = 1
print "a=", a, "
"
end
end
Результатом будет:
a=1 Function 'a' called a=99
Во время разбора кода Ruby, встречая "а" в первой инструкции "print", делает вывод, что это вызов метода.
Когда Ruby подбирается ко второму "print", на его пути уже встречалось присваивание "а", и "а" рассматривается как переменная.
Заметьте, что само присваивание не обязательно должно быть выполнено. Следующая программа не является ошибочной:
a = 1 if false; a
Обычно эта особенность переменных не является проблемой, но если вы все же столкнулись с ней, поставьте перед первым упоминанием переменной присваивание типа a = nil. Это оказывает дополнительный эффект на скорость доступа к локальным переменным внутри цикла.
