Когда локальная переменная становится доступной?

На самом деле этот вопрос лучше задать так: "На какой стадии 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. Это оказывает дополнительный эффект на скорость доступа к локальным переменным внутри цикла.

Вход для пользователей