if (! x) против if (x == false) в рубине - PullRequest
11 голосов
/ 21 июня 2010

Я не понимаю следующий код:

ruby-1.9.1-p378 > puts "nil is false" unless nil
nil is false
 => nil 
ruby-1.9.1-p378 > puts "nil isn't false" unless nil == false
nil isn't false
 => nil 

В большинстве языков (по крайней мере на основе C) if (! Cond) и if (cond == false) оценивают одинаково. Что здесь происходит, чтобы это не так?

(Мне бы хотелось узнать, почему, я так понимаю.)

Ответы [ 3 ]

31 голосов
/ 21 июня 2010

Руби считает, что false и nil являются единственными двумя "ложными" значениями, в то время как все остальное является "правдивым". Это по определению и не может быть изменено (по крайней мере, в МРТ). Это определение используется для всех встроенных операторов, таких как if, unless, while, until, cond ? if_truthy : if_falsey, ||, &&, ...

Запись foo == bar всегда вызывает метод == для foo с bar в качестве аргумента. По умолчанию nil, false, true и все другие непосредственные объекты, такие как символы и т. Д., Равны только себе. Это можно изменить, хотя:

def nil.==(bar)
  super || bar == false
end
puts "nil == false" if nil == false  # => "nil == false"

В Ruby 1.9 вы также можете переопределить оператор !, поэтому unless foo не обязательно совпадает с if !foo или наоборот if foo:

def true.!
  true
end

puts "True?"   if  true # => "True?"
puts "or not?" if !true # => "or not?"

Не то, чтобы кто-нибудь рекомендовал бы делать что-то подобное ...

2 голосов
/ 21 июня 2010

nil не равно ложному при сравнении с ==, потому что их семантическое содержание отличается (nil не информация, false - логическое значение). Однако, если вы попытаетесь оценить nil в логическом контексте, это будет считаться ложным, в основном для удобства и идиоматической совместимости с другими языками.

nil == a <=> nil != a <=> false будет иметь место практически для любого значения, кроме нуля.

Таким образом, вы можете только сказать, что «ноль - это не правда» и «ноль - это ноль». Это так далеко, как рубин идет своим путем.

0 голосов
/ 21 июня 2010

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

В Ruby, однако, все можно считать булевым, дажехотя на самом деле это не так.На самом деле все в Ruby действительно верно, кроме nil и false (IIRC).Это не означает, что nil на самом деле РАВНО к ложному, точно так же, как это не означает, что целое число 45 на самом деле равно к истинному.Они разные, разные вещи.Но если вы собираетесь относиться к nil как к булевому (то есть использовать его в операциях if или uns), то это как если бы оно было ложным.

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