Оба |
и ||
являются операторами . ||
является частью языка, в то время как |
реализован в виде метода некоторыми классами (Array
, FalseClass
, Integer
, NilClass
и TrueClass
).
В языках программирования |
обычно используется как оператор побитового ИЛИ . Он объединяет биты своих целочисленных операндов и выдает новое целочисленное значение. При использовании с нецелыми операндами некоторые языки преобразуют их в целочисленные, другие запрещают такое использование.
||
- логический оператор ИЛИ . Он объединяет два логических значения (true
или false
) и создает другое логическое значение. Когда его операнды не являются логическими значениями, они конвертируются в логические значения в некоторых языках. Ruby (и JavaScript и другие языки) оценивают свой первый операнд как логический, и значение выражения является значением его первого операнда, если его логическое значение равно true
, или значением его второго операнда, если логическое значение его первого это false
. Тип полученного значения является его исходным типом, он не преобразуется в логическое значение.
Каждый язык использует свои собственные правила, чтобы решить, какие небулевые значения преобразуются в false
(обычно это число 0
, пустая строка ''
и null
или undefined
); все остальные значения преобразуются в true
. Единственными «ложными» значениями в Ruby являются false
(логическое значение) и nil
(не логическое значение); все остальные значения (включая 0
) имеют значение «истина».
Поскольку true || anything
равно true
и false && anything
равно false
, многие языки программирования, включая Ruby, оценка короткого замыкания для логического выражения.
Используя оценку короткого замыкания , логическое выражение вычисляется слева направо, один операнд за раз, пока значение выражения не может быть вычислено без необходимости вычисления других операндов. В приведенных выше примерах значение anything
не меняет значение всего выражения. При использовании оценки короткого замыкания значение anything
вообще не вычисляется, поскольку оно не влияет на значение всего выражения. Будучи anything
вызовом метода, выполнение которого занимает значительное время, оценка короткого замыкания избегает его вызова и экономит время выполнения.
Как уже упоминалось в комментариях к этому вопросу, реализация ||
в качестве метода некоторого класса невозможна. Значение его второго операнда должно быть оценено, чтобы быть переданным в качестве аргумента методу, и это нарушает поведение короткого замыкания.
Обычное представление логических значений в языках программирования использует только один бит (и я полагаю, что Ruby делает то же самое). Результаты |
и ||
одинаковы для операндов, хранящихся в одном бите.
Ruby использует символ |
для реализации различных вариантов операции OR
следующим образом:
Выражение типа:
x = false | a | b | c
обеспечивает оценку всех выражений a
, b
и c
(без короткого замыкания), а значение x
представляет собой логическое ИЛИ логических значений a
, b
и c
.
Если a
, b
и c
являются вызовами методов, для достижения того же результата с помощью оператора логического ИЛИ (||
) код должен выглядеть следующим образом:
aa = a
bb = b
cc = c
x = aa || bb || cc
Таким образом, каждый метод вызывается независимо от того, какие значения возвращаются методами, вызванными до него.
Для TrueClass
, FalseClass
и NilClass
оператор |
полезен, когда оценка короткого замыкания нежелательна.
Кроме того, для Array
(массив - это просто упорядоченный набор) оператор |
реализует объединение, операцию, которая семантически эквивалентна логическому ИЛИ для наборы.