Разница между или и || в Ruby?

В чем разница между операторами or и || в Ruby? Или это просто предпочтение?


person Alex Baranosky    schedule 17.01.2010    source источник
comment
См. Также Разницу между and и &&.   -  person Andrew Marshall    schedule 18.05.2012
comment
Для получения информации о семантике см. Использование " and »и« или »в Ruby   -  person Stefan    schedule 25.10.2019


Ответы (8)


Это вопрос приоритета оператора.

|| имеет более высокий приоритет, чем or.

Итак, между этими двумя у вас есть другие операторы, включая тернарный (? :) и присваивание (=), так что какой из них, который вы выберете, может повлиять на результат операторов.

Вот таблица приоритета рубиновых операторов.

См. этот вопрос для другого примера с использованием _5 _ / _ 6_.

Также помните о некоторых неприятных вещах, которые могут произойти:

a = false || true  #=> true
a  #=> true

a = false or true  #=> true
a  #=> false

Оба предыдущих двух оператора вычисляют true, но второй устанавливает a в false, поскольку приоритет = ниже, чем ||, но выше, чем or.

person mopoke    schedule 17.01.2010

Как уже объяснили другие, единственное отличие - это приоритет. Однако я хотел бы отметить, что на самом деле между ними есть два различия:

  1. and, or и not имеют намного более низкий приоритет, чем &&, || и !
  2. and и or имеют одинаковый приоритет, а && имеет более высокий приоритет, чем ||

В общем, рекомендуется избегать использования and, or и not и использовать вместо них &&, || и !. (Разработчики ядра Rails, например, отклоняют патчи, которые используют формы ключевых слов вместо форм операторов.)

Причина, по которой они вообще существуют, не в булевых формулах, а в потоке управления. Они проникли в Ruby через известную идиому Perl do_this or do_that, где do_this возвращает false или nil в случае ошибки и только тогда do_that вместо этого выполняется. (Аналогично, есть идиома do_this and then_do_that.)

Примеры:

download_file_via_fast_connection or download_via_slow_connection
download_latest_currency_rates and store_them_in_the_cache

Иногда это может сделать поток управления немного более плавным, чем использование if или unless.

Легко понять, почему в этом случае операторы имеют «неправильный» (т. Е. Идентичный) приоритет: в любом случае они никогда не появляются вместе в одном выражении. И когда они действительно появляются вместе, вы обычно хотите, чтобы они оценивались просто слева направо.

person Jörg W Mittag    schedule 18.01.2010
comment
Это иногда сбивает меня с толку, потому что в Perl and имеет более высокий приоритет, чем or, что отражает && и ||. Но обычно вам все равно не следует связывать длинные сложные серии из них вместе. - person ephemient; 18.01.2010
comment
Интересно, я этого не знал. Я никогда активно не использовал Perl и не изучал его. - person Jörg W Mittag; 18.01.2010
comment
Хороший ответ - я не знал о том, что такое равный приоритет, звучит как авария, ожидающая своего часа. - person klochner; 18.01.2010
comment
Неа. and всегда предпочтительнее &&, если не заниматься сложной булевой алгеброй. Это более читабельно. - person Marnen Laibow-Koser; 02.11.2011
comment
Что касается проблемы приоритета, если у вас есть более одного and или or без скобок, ваш код все равно не будет читаться, и вам следует его реорганизовать. - person Marnen Laibow-Koser; 02.11.2011
comment
Короче говоря, Йорг, ты здесь неправ. if this_condition or that_condition не является булевой алгеброй, кроме как в самом педантичном смысле; скорее, это поток управления, и поэтому он вполне приемлем. - person Marnen Laibow-Koser; 02.11.2011
comment
НЕ слушайте @ MarnenLaibow-Koser - это не имеет ничего общего с удобочитаемостью и полностью связано с тем фактом, что разница в приоритете приведет к разным результатам в самых основных логических операциях: например, true && false! = true and false, false or true! = false || true. - person Yarin; 13.09.2013
comment
@Yarin Precedence становится проблемой только тогда, когда вы начинаете операции вложения без скобок. Ваш пример true && false фактически эквивалентен true and false, потому что нет проблемы с приоритетом. Аналогично, (x > 1) and (x < 4) в рабочем состоянии эквивалентен (x > 1) && (x < 4), потому что все приоритеты выполняются с использованием скобок. В этих случаях выбор сводится исключительно к удобочитаемости. - person Marnen Laibow-Koser; 13.09.2013
comment
@Yarin На самом деле, ваш пример не показывает то, что вы думаете. true && false эквивалентно true and false. Различия в вашем примере вызваны исключительно проблемами неявного приоритета: print true and false эквивалентно print(true) and false, тогда как print true && false эквивалентно print(true && false). Вы довольно хорошо доказали мою точку зрения - приоритет вступает в игру только тогда, когда вы встречаете операции без скобок. - person Marnen Laibow-Koser; 15.09.2013
comment
@Yarin Похоже, я здесь наполовину ошибся; похоже, что print(true and false) - это синтаксическая ошибка, о которой я не знал. - person Marnen Laibow-Koser; 15.09.2013

_1 _ / _ 2_ предназначены для потока управления.

Ruby не допускает этого как допустимого синтаксиса:

false || raise "Error"

Однако это действительно так:

false or raise "Error"

Вы можете сделать первую работу с (), но использование or - правильный метод.

false || (raise "Error")
person Eadz    schedule 09.04.2014
comment
эээ интересно, почему это было отклонено. Во втором верхнем ответе говорится, что единственная разница - это приоритет, но на моем примере вы можете видеть, что это не так. - person Eadz; 09.04.2014
comment
Это действительно явно демонстрирует, что принятый ответ (очень немного) неверен. Насколько вам известно, задокументировано ли где-нибудь поведение, которое вы здесь демонстрируете? - person Mark Amery; 03.12.2014
comment
Тот факт, что это неверный синтаксис, является следствием приоритета оператора. Raise не возвращает, поэтому не может быть оценено как выражение. - person bluehallu; 13.07.2016

puts false or true -> выводит: ложь

puts false || true -> выводит: верно

person Radek Secka    schedule 03.06.2016
comment
Это если вы передаете это методу. Сам по себе он всегда возвращает истину - person Paul Brunache; 22.08.2017

Как я использую эти операторы:

||, && предназначены для логической логики. or, and предназначены для потока управления. Например.

do_smth if may_be || may_be - оцениваем состояние здесь

do_smth or do_smth_else - мы определяем рабочий процесс, что эквивалентно do_smth_else unless do_smth

чтобы дать простой пример:

> puts "a" && "b"
b

> puts 'a' and 'b'
a

Хорошо известная идиома в Rails - render and return. Это ярлык для слов return if render, а render && return не сработает. См. «Как избежать ошибок двойного рендеринга» в документации по Rails. Дополнительная информация.

person Vadym Tyemirov    schedule 19.07.2015
comment
Спасибо за объяснение точки оператора or :) - person jayqui; 25.06.2019

or НЕ то же самое, что ||. Используйте только оператор || вместо оператора or.

Вот несколько причин. В:

  • Оператор or имеет более низкий приоритет, чем ||.
  • or имеет более низкий приоритет, чем оператор присваивания =.
  • and и or имеют одинаковый приоритет, а && имеет более высокий приоритет, чем ||.
person vel pradeep.MS    schedule 12.03.2014
comment
Я категорически не согласен с этим; and и or действительно занимают свое место в потоке управления; например, вы можете написать if a==b and c==d и можете быть уверены, что and имеет самый низкий приоритет. Это также выглядит намного приятнее для людей за пределами мира C. - person DarkWiiPlayer; 23.04.2018

Оба or и || оцениваются как истинные, если любой из операндов истинен. Они оценивают свой второй операнд, только если первый ложен.

Как и в случае с and, единственное различие между or и || - их приоритет.

Чтобы сделать жизнь интересной, and и or имеют одинаковый приоритет, а && имеет более высокий приоритет, чем ||.

person cvibha    schedule 13.03.2014
comment
Нет не правда. a = false or true, там будет присвоено false. - person Anwar; 01.02.2017

Просто чтобы добавить к ответу mopoke, это также вопрос семантики. or считается хорошей практикой, потому что он читается намного лучше, чем ||.

person rogeriopvl    schedule 18.01.2010
comment
Я не знаю, на стороне ли оператора или передовая практика. Случай аналогичен скобкам для аргументов. Вызов методов без них часто лучше читается, но в некоторых случаях они приводят к странным ошибкам. Раньше я выборочно использовал или и отбрасывал парные скобки, но в конце концов я просто отказался от них, потому что довольно часто они не могли использоваться, в некоторых случаях я забывал и вводил ошибку, и предпочел последовательность, просто всегда используя парные скобки и ||. Ситуация как минимум дискуссионная. - person tfwright; 18.01.2010
comment
вы имеете в виду, что это вопрос синтаксиса :) они оба имеют одинаковую семантическую интерпретацию (приоритет оператора по модулю) - person klochner; 18.01.2010
comment
Если вы полагаетесь на приоритет логической арифметики, ваш код все равно не читается. Добавьте круглые скобки или выполните рефакторинг. - person Marnen Laibow-Koser; 03.11.2011
comment
Это должен быть комментарий, а не ответ. - person the Tin Man; 22.11.2019