Рубин:
true == true == true
синтаксическая ошибка, неожиданный tEQ
по сравнению с JavaScript:
true == true == true
// => true
по сравнению с C:
1 == 1 == 1
// => 1
Рубин:
true == true == true
синтаксическая ошибка, неожиданный tEQ
по сравнению с JavaScript:
true == true == true
// => true
по сравнению с C:
1 == 1 == 1
// => 1
Направление ассоциации, которое управляет порядком операторов, оценивающих свои аргументы, не определено для метода ==
, так же как и для методов ===
, !=
, =~
и <=>
(все они имеют одинаковый приоритет и образуют отдельную группу приоритета исключительно ).
Таким образом, порядок вычислений в случае, когда несколько операторов из списка, упомянутого выше, выстраиваются в цепочку в строке, должен быть установлен явно через либо
скобка ()
:
(true == true) == true # => true
true == (true == true) # => true
или оператор точки .
(можно опустить для последней проверки на равенство в строке):
true .== true == true # => true
1 == 1 == 1
будет оцениваться как false
в Ruby, если ==
будет левоассоциативным, что, вероятно, приведет к нескольким ошибкам. И это тоже не имело бы особого смысла — единственными разумными значениями для третьего операнда являются true
и false
, то есть a == b == true
и a == b == false
, которые можно выразить как a == b
и a != b
.
- person Stefan; 09.01.2018
==
можно переопределить в пользовательском классе, и, таким образом, проверка на равенство может вернуть что-то отличное от true
или false
(например, nil
)
- person potashin; 09.01.2018
Если я правильно понимаю вопрос, value_a == value_b == value_c
должен возвращать true только в том случае, если все они равны, используя == в качестве оператора сравнения, как показано в этом методе.
# version 1
def compare#version 2
def compare_3_values(a, b, c)
(a == b) == c
end
values(a, b, c)
a == b && a == c && b == c
end
хотя есть и другой возможный ожидаемый результат. чтобы реализовать это, как показано в предыдущем ответе:
#version 2
def compare_3_values(a, b, c)
(a == b) == c
end
Результаты совершенно разные.
JavaScript всегда использует версию 2, что довольно бесполезно, так как 3-й элемент всегда сравнивается с истинным или ложным (0 или 1, если 3-й элемент является целым числом), поэтому false == false == true
возвращает истину.
Хорошая новость заключается в том, что, поскольку ruby выдает синтаксическую ошибку, это единственный язык, который может реализовать это, не нарушая общий код.
для любого другого языка это сломало бы так много кода, что даже если бы он был реализован в более поздней основной версии, потребовался бы флаг/настройка, чтобы включить или выключить это на долгие годы, поэтому это никогда не будет стоить.
Некоторые интересные результаты в Ruby
false .== false == true
=> true
false .== true == false
=> true
true .== false == false
=> true
false .== false == false
=> false
true .== true == false
false
И в джаваскрипте
false == false == true
=> true
false == true == false
=> true
true == false == false
=> true
false == false == false
=> false
true == true == false
=> false
Редактирование, также протестированное в C, действует аналогично JavaScript, поскольку сравнивает результат первых двух значений с третьим значением.
первый ответ превосходен, но на случай, если он не совсем ясен (и люди спрашивают, почему), вот еще несколько примеров .
В C оператор ==
является ассоциативным слева направо, а логическое значение представлено как 1 (истина) и 0 (ложь), поэтому первый 1 == 1
оценивается как 1
(истина), а затем вы оцениваете результат первого выражения с помощью второй. Можешь попробовать:
2 == 2 == 2 // => 0
Который в C оценивается как:
(2 == 2) == 2
1 == 2 // => 0
В Javascript, как и в C, ==
ассоциативен слева направо. Давайте попробуем на этот раз с 0 (хотя тот же пример из C тоже сработает):
0 == 0 == 0
false
Опять таки:
0 == 0 == 0
true == 0 // => false
В Ruby ==
не имеет ассоциативных свойств, т.е. его нельзя использовать несколько раз в одном выражении, поэтому выражение нельзя вычислить. Почему было принято такое решение — вопрос к автору языка. Кроме того, Ruby не определяет число 1 как логическое значение, поэтому 1 == true
оценивается как false.
Во втором ответе говорится, что в Ruby есть некоторые "странные" случаи, но все они оцениваются так, как ожидалось:
(1 == 1) == 1
true == 1 # => false
1 == (1 == 1)
1 == true # => false
1 .== 1 == 1
(1 == 1) == 1
true == 1 # => false
false .== false == true
(false == false) == true
true == true # => true
false .== true == false
(false == true) == false
false == false # => true
true .== false == false
(true == false) == false
false == false # => true
false .== false == false
(false == false) == false
true == false # => false
true .== true == false
(true == true) == false
true == false # => false
==
,===
и!=
). Даже<
и>
анализируются правильно, а затем выдают ошибку времени выполнения, как и следовало ожидать. Кроме того, только sources Я могу найти, какое утверждение о наличии полной грамматики для Ruby указывает на то, что этот синтаксис допустимый. - person Silvio Mayolo   schedule 09.01.2018true .== true .== true
- person potashin   schedule 09.01.2018==
указан как неассоциативный (A=N)< /b> в ответе, что означает, что такая продукцияX==Y==Z
недействительна (ассоциативность — это то, что добавляет неявные круглые скобки вокруг операторов с одинаковым приоритетом). В вопросе есть много ссылок, которые могут вести к более официальному источнику, который можно было бы четко процитировать. (Этот вопрос скорее касается конкретного подмножества/применения грамматических правил в этом вопросе/ответе.) - person user2864740   schedule 09.01.2018<
и друзья являются левоассоциативными.. поэтому должны анализироваться (и работать, учитывая действительные входные данные во время выполнения). Я не уверен, какова грамматическая рациональность в отношении того, почему<
будет ассоциативным, а==
— нет, хотя изменение этого может сломать многие ожидания. - person user2864740   schedule 09.01.2018==
неассоциативным, но все же позволять<
и компании иметь ассоциативность. - person Silvio Mayolo   schedule 09.01.2018