Ruby 2.2.4 lexing присвоение в условном
В чем разница между этими двумя строками кода?
a = (b if (b = "test"))
a = b if (b = "test")
Первый работает отлично и задает как a
и b
для test
, но второй вызывает ошибку:
NameError: неопределенная локальная переменная или метод 'b' для main: Object
Я бы предположил, что для второй строки Ruby сначала оценил b = "test"
, затем if "test"
и, наконец, a = b
. Что на самом деле происходит?
(Версия Ruby версии 2.2.4)
Обе линии не будут работать. И обе линии будут работать. Это выражение schrödinger :).
Вы можете запустить его дважды в новом реплике:
a = b if b = "test"
#=> NameError: undefined local variable or method 'b' for main:Object
a = b if b = "test"
#=> "test"
Давайте посмотрим глубже, откройте новую реплику:
defined(b)
#=> nil
a = b if b = "test"
#=> NameError: undefined local variable or method 'b' for main:Object
defined(b)
#=> local-variable
b
#=> "test"
a = b if b = "test"
#=> "test"
Таким образом, на самом деле Ruby оценил часть b = "test"
и определил эту переменную в текущей области. Оба выражения a = b
и if b = "test"
выполнялись. Более того, если оператор выполнения выполняется перед оператором присваивания:
c = p("assignment") && b if b = p("if") && "test"
#=> "if"
#=> "assignment"
#=> NameError: undefined local variable or method 'b' for main:Object
Но переменная b
не была определена в области применения присваивания, когда она была впервые оценена. А на втором подходе он уже был определен, поэтому вы получили правильный результат.
Итак, никогда не выполняйте задания таким образом
- Вопросы
- Conditional
- Ruby 2.2.4 lexing присвоение в условном