У Рубі є універсальне уявлення про « правдивість » та « хибність ».
Рубін робить два конкретних класів для об'єктів Boolean, TrueClass
і FalseClass
, з одноплідними випадками , позначених спеціальними змінними true
і false
, відповідно.
Однак правдивість і хибність не обмежуються примірниками цих двох класів, концепція є універсальною і застосовується до кожного об'єкта в Ruby. Кожен об'єкт є або truthy або falsy . Правила дуже прості. Зокрема, лише два об'єкти є хибними :
nil
, одиничний екземплярNilClass
іfalse
, одиночний екземплярFalseClass
Кожен інший об'єкт є правдою . Сюди входять навіть об'єкти, які вважаються хибними в інших мовах програмування, наприклад
Ці правила вбудовані в мову і не визначаються користувачем. Немає to_bool
неявного перетворення чи нічого подібного.
Ось цитата зі специфікації мови ISO Ruby :
6.6 Булеві значення
Об'єкт класифікується або в істинний об'єкт, або в хибний об'єкт .
Тільки брехня і нуль є falseish об'єктів. false - єдиний екземпляр класу
FalseClass
(див. 15.2.6), для якого оцінюється хибний вираз (див. 11.5.4.8.3). nil - єдиний екземпляр класуNilClass
(див. 15.2.4), якому оцінюється вираження nil (див. 11.5.4.8.2).Об'єкти, крім БРЕХНІ і нуля підрозділяється на trueish об'єкти. true - єдиний екземпляр класу
TrueClass
(див. 15.2.5), якому оцінюється істинний вираз (див. 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 . Усі три реалізації реально погоджуються між собою та не згодні зі специфікацією ISO Ruby Language та моїм тлумаченням Ruby / Spec.
Точніше, Regexp
об'єкти, які є результатом оцінювання Regexp
літералів, є хибними , тоді як Regexp
об'єкти, які є результатом якогось іншого виразу, є правдою :
r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
Це помилка чи бажана поведінка?
!!//
помилково, але !!/r/
є правдою. Дивно насправді.
!!/r/
виробляє false
для мене, використовуючи (RVM) Ruby 2.4.1.
//
в if // then
інтерпретується як тест (ярлик для if //=~nil then
) (який завжди хибний, незалежно від шаблону), а не як екземпляр Regexp.
Regex.new("a")
це правда.