|| и && не являются методами на объекте - что они? - PullRequest
0 голосов
/ 04 июля 2018

Один канал "или" | существует как метод для TrueClass и FalseClass, а оператор короткого замыкания || - нет. Он также не существует как метод в Object.

Это, похоже, исключение из метафоры ruby ​​"все является объектом".

Основной вопрос: С синтаксической точки зрения, что есть || и &&? Они просто испекли кусочки глобального синтаксиса?

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

Есть ли причина такой асимметрии в конструкции языка или производительности? Мне кажется, что оба оператора могли бы быть реализованы как методы на Object. Что-то вроде:

class Object
  def short_circuit_or(other)
    !nil?       ? true : 
    !other.nil? ? true : false
  end
end

Полагаю, есть причина, по которой они не были. Что это?

1 Ответ

0 голосов
/ 05 июля 2018

Оба | и || являются операторами . || является частью языка, в то время как | реализован в виде метода некоторыми классами (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 (массив - это просто упорядоченный набор) оператор | реализует объединение, операцию, которая семантически эквивалентна логическому ИЛИ для наборы.

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