Что значит @foo ||@foo = "bar" значит в Ruby и почему? - PullRequest
0 голосов
/ 02 февраля 2019

Что означает @foo || @foo = "bar" в Ruby?Мне кажется, это имеет значение @foo || (@foo = "bar") вместо (@foo || @foo) = "bar".Это, однако, противоречит тому факту, что || имеет более высокий приоритет, чем = в Ruby .

Мне известно, что || в Ruby является оператором короткого замыкания.Я также понимаю, что || должен оцениваться до = в соответствии с приоритетом.Что я не понимаю, так это то, что @foo = "bar" кажется правильным оперантом ||.Согласно таблице приоритетов , правый оперант || должен быть @foo, а выражение должно быть эквивалентно (@foo || @foo) = "bar", что недопустимо.

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

Я думаю, в конце концов, это действительно просто оценка короткого замыкания, как Рэй упоминает в своем ответе, но я думаю, что в этом отношении документации не хватает.

|| - оператор короткого замыканиятак как оценка продолжается слева направо, как только она находит истину, она завершается и возвращает истину, в противном случае она переходит вправо

на modifier-if (также указано на странице, на которую вы ссылались)) имеет более низкий приоритет, чем присвоение =, однако присвоение не является оператором короткого замыкания, поэтому код типа

foo = "not set"
is_true = false
foo = 42 if is_true
puts foo 

будет печатать

не установлено

в то время как код, такой как:

foo = "not set"
is_true = true 
foo = 42 if is_true 
puts foo 

будет печатать

42

|| является оператором короткого замыкания, поэтому такой код:

foo = 0 
foo || foo = 42
puts foo 

напечатает

0

, поскольку foo для левой руки не равен нулю, поэтому нет смысла оценивать правую часть.

в то время как код такой:

foo = nil
foo || foo = 42
puts foo 

напечатает

42

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

Я согласен, однако, что документ, на который вы указываете, подразумевал бы, что

x || y = z должен быть основан наприоритет может быть истолкован как (x || y) = z, что не будет законным.Однако также очевидно, что это было бы то же самое, что и попытка присвоить значение логическому значению.

Например:

(true || true) = 42 

- синтаксическая ошибка

, как и:

a = nil
b = nil
(a || b) = 42

пока

a = nil
b = nil 
a || b = 42
puts b

приводит к

42

0 голосов
/ 03 февраля 2019

Проще говоря, ваша интерпретация правила приоритета неверна.

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

@foo || @foo = ...

может интерпретироваться только как

@foo || (@foo = ...)

и здесь нет двусмысленности, следовательно, нет проблемы приоритета.

То, что касается правила приоритета, - это правая часть =.Говорят, что

@foo = bar || baz

интерпретируется как

@foo = (foo || baz)

, а не

(@foo = foo) || baz
0 голосов
/ 02 февраля 2019

Ruby использует Оценка короткого замыкания , и поэтому он оценивает первый аргумент, чтобы решить, следует ли продолжать со вторым.

В случае @foo || @foo = "bar" операция ИЛИ имеет видвыполняется таким образом, что, когда первый аргумент найден nil, оценивается второй аргумент, который является оператором присваивания.Если первый аргумент найден / правдив, то он проигнорирует второй аргумент (в данном случае оператор). Примечание. Он не просто присваивает значение @foo, полное логическое утверждение возвращает значение после присваивания.

Если вы пишете,@foo = @foo || 'sd' Сначала выполняются логические операции, а затем назначаются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...