Оператор И возвращает второе значение, если первое истинно, первое, если оно ложно

1 && 2 ---> 2
0 && 1 ---> 0

Почему операция ИЛИ не возвращает второе значение, если первое ложно, но возвращает первое, если оно истинно

0 || 1 ---> 0
1 || 0 ---> 1
1
Cụt Cánh 6 Сен 2016 в 13:30

3 ответа

Лучший ответ

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

И на самом деле ваш пример неверен:

irb> 0 && 1
=> 1

Этого и следовало ожидать, поскольку 0 в Ruby истинно, а не ложно, как в C.

В случае ИЛИ он может остановиться, как только попадет во что-то правдивое, и не нужно беспокоиться об остальном.

0 || false      # => 0
false || 0      # => 0
false || 0 || 2 # => 0

Если вы хотите принудительно преобразовать такое выражение в логическое значение, вы часто видите, как это делается:

!!(expression)
!!(0 || 1)        => true
!!(nil || false)  => false 
2
Ginty 6 Сен 2016 в 10:41

|| является логическим оператором, а не побитовым оператором. В отличие от других языков, например, C, 0 не является «ложным» значением в ruby.

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

определенное значение "0" || определенное значение "1"

Какой рубин правильно оценивается как истинное выражение A || истинное выражение B и возвращающее истинное выражение A , то есть 0.

См. Здесь: https://gist.github.com/jfarmer/2647362

Для хорошего обзора значений "Truthy" и "Falsey" в Python и Ruby.

1
mcfinnigan 6 Сен 2016 в 10:35

И OR, и AND оцениваются по короткому замыканию, как только они узнают значение выражения, которое они передают вам. В Ruby и 0, и 1 являются истинными, это истинные значения. Так

0 || 1 is 0

Потому что 0 - это правда. Просто nil || 1 или false || 1 вернет 1.

3
Ursus 6 Сен 2016 в 10:35