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

Почему оператор возврата прерывает условный оператор?

Экспериментируя с условным оператором в рубине,

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

также работает как ожидалось.

Итак, что с условным (тройным) оператором?

4b9b3361

Ответ 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, значение переменной не назначается.