Почему оператор возврата прерывает условный оператор?
Экспериментируя с условным оператором в рубине,
def nada
false ? true : nil
end
def err
false ? true : raise('false')
end
работает как ожидалось, но
def reflection
false ? true : return false
end
создает a syntax error, unexpected keyword_false, expecting keyword_end
def reflection
false ? true : return(false)
end
и попытался с помощью скобок syntax error, unexpected tLPAREN, expecting keyword_end
пока
def reflection
false ? true : (return false)
end
работает так, как ожидалось, и более подробный if
... then
... else
... end
def falsy
if false then true else return false end
end
также работает как ожидалось.
Итак, что с условным (тройным) оператором?
Ответы
Ответ 1
Вы можете использовать его таким образом, поместив в круглые скобки все выражения return
:
def reflection
false ? true : (return false)
end
Конечно, это не имеет особого смысла, как это, но, поскольку вы экспериментируете (хорошо!), это работает! Ошибка связана с тем, как работает грамматика Ruby, она предполагает, что определенная структура сформирует правильное выражение.
UPDATE
Указание некоторой информации из спецификации проекта:
Выражение представляет собой программную конструкцию, которая составляет утверждение (см. 12). Единственное выражение может быть выражением как выражение-выражение (см. 12.2).12
ПРИМЕЧАНИЕ. Дифференциация между выражением и утверждением состоит в том, что выражение обычно используется там, где требуется его значение, но обычно используется, когда его значение не обязательно обязательный. Однако есть некоторые исключения. Например, jump-expression (см. 11.5.2.4) не имеет значения, а значение из последней инструкции составного оператора.
NB. В приведенном выше примере выражение перехода включает в себя return
среди других.
Ответ 2
Я думаю, что все это связано с рубиновым парсером.
- ruby анализирует
return
как else-выражение тернарного оператора
- ruby затем удивляется, когда находит
false
вместо end
- wrapping
return false
в круглых скобках заставляет ruby интерпретировать всю вещь как else-expression
-
return(false)
не работает, потому что ruby все еще пытается интерпретировать только часть return
как else-выражение, и удивляется, когда находит скобку слева (обновляется)
Примечание. Я не думаю, что это отличный ответ.
Большой ответ мог бы, например, объяснить ошибки разбора со ссылкой на рубиновую грамматику.
Ответ 3
Оператор ternery - это просто оператор. Вы не возвращаетесь от него. Вы возвращаетесь из функций. Когда вы возвращаете значение в if, вы возвращаетесь из функции, в которой находится if. Поскольку нет переменной, ожидающей назначения из результата if, нет проблем. Когда вы возвращаетесь из оператора ternery, значение переменной не назначается.