Ruby имеет универсальную идею " истинность " и " ложь ".
Ruby имеет два специальных класса для логических объектов, TrueClass
и FalseClass
, причем единичные экземпляры обозначаются специальными переменными true
и false
соответственно.
Однако истинность и ложность не ограничиваются экземплярами этих двух классов, концепция универсальна и применяется к каждому отдельному объекту в Ruby. Каждый объект является либо правдивым , либо ложным . Правила очень просты. В частности, только два объекта являются ложными :
Каждый отдельный объект равен правдиво . Это включает даже объекты, которые считаются ложными на других языках программирования, таких как
Эти правила встроены в язык и не могут быть определены пользователем. Не существует to_bool
неявного преобразования или чего-либо подобного.
Вот цитата из Спецификации языка Ruby ISO :
6.6 Булевы значения
Объект классифицируется как истинный объект или ложный объект .
Только false и nil являются ложными объектами. false - единственный экземпляр класса FalseClass
(см. 15.2.6), которому оценивается ложное выражение (см. 11.5.4.8.3). nil - единственный экземпляр класса NilClass
(см. 15.2.4), для которого nil-выражение оценивает (см. 11.5.4.8.2).
Объекты, отличные от false и nil , классифицируются как истинные объекты. true является единственным экземпляром класса TrueClass
(см. 15.2.5), которому оценивается true-выражение (см. 11.5.4.8.3).
Кажется, что исполняемый Ruby / Spec согласен :
it "considers a non-nil and non-boolean object in expression result as true" do
if mock('x')
123
else
456
end.should == 123
end
Согласно этим двум источникам, я бы предположил, что Regexp
s также правдиво , но, согласно моим тестам, это не так:
if // then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are falsy'
Я проверял это на YARV 2.7.0-preview1 , TruffleRuby 19.2.0.1 и JRuby 9.2.8.0 . Все три реализации согласуются друг с другом и не согласуются со Спецификацией языка Ruby ISO и моей интерпретацией Ruby / Spec.
Точнее, Regexp
объектов, которые являются результатом оценки литералов Regexp
являются ложными , тогда как Regexp
объектами, которые являются результатом какого-либо другого выражения, являются правдивые :
r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
Является ли это ошибкой или желательноповедение?