Подтвердить что ты не робот

Ruby, если vs конец строки, если ведут себя по-другому?

Почему этот код не работает?

b if b = true

Ошибка: undefined local variable or method `b'

Но это делает:

if b = true
    b
end

Разве они не должны быть одинаковыми?

4b9b3361

Ответ 1

Это очень хороший вопрос. Это связано с областью определения переменных в Ruby.

Вот сообщение от Matz на трекер-бугере Ruby об этом:

Локальная область видимости переменной определяется вниз, слева направо. Таким образом, локальная переменная, сначала назначенная в условии, если модификатор не действует в левой части, если тело. Это спецификация.

Ответ 2

В первой версии, как только k попадает, анализатор pukes, потому что он еще не был замечен.

Во второй версии k является частью выражения присваивания и анализируется по-разному.

Ответ 3

Я не знаю причину, кроме проблемы, которую интерпретатор пытается найти переменную k перед оценкой состояния.

Если вы напишете это так, ошибок не будет и работает так, как вы ожидали:

k = nil
h = {k: 1}
v = k if k = h.delete(:k)

Ответ 4

Поскольку интерпретатор Ruby создает локальную переменную, когда видит назначение

Во втором случае он еще не видел назначение, поэтому переменная не существует, когда выражение анализируется.

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

Локальные переменные создаются в этом сеансе синтаксического анализа. Это вопрос декларации, это просто означает, что интерпретатор узнает о них. Они не будут созданы в смысле предоставления пространства или значения, пока кто-то не вызовет окружающий метод.