Ruby ma uniwersalną ideę „ prawdy ” i „ fałszu ”.
Ruby ma mieć dwie klasy specyficzne dla Boolean obiektów, TrueClass
i FalseClass
, z pojedynczych przypadkach oznaczonych zmiennych specjalnych true
i false
, odpowiednio.
Jednak prawdomówność i fałsz nie ograniczają się do przypadków tych dwóch klas, koncepcja jest uniwersalna i dotyczy każdego obiektu w Rubim. Każdy przedmiot jest prawdomówny lub fałszywy . Zasady są bardzo proste. W szczególności tylko dwa obiekty są fałszywe :
nil
, pojedyncza instancjaNilClass
ifalse
, singleton wystąpienieFalseClass
Każdy inny przedmiot jest prawdziwy . Obejmuje to nawet obiekty, które są uważane za fałsz w innych językach programowania, takich jak
Reguły te są wbudowane w język i nie są definiowane przez użytkownika. Nie ma to_bool
niejawnej konwersji lub czegoś podobnego.
Oto cytat ze specyfikacji języka Ruby ISO :
6.6 Wartości logiczne
Obiekt jest klasyfikowany do obiektu prawdziwego lub fałszywego .
Tylko fałsz i zero są fałszywymi obiektami. false jest jedynym wystąpieniem klasy
FalseClass
(patrz 15.2.6), do którego odnosi się wyrażenie fałszywe (patrz 11.5.4.8.3). zero jest jedynym wystąpieniem klasyNilClass
(patrz 15.2.4), do którego ewaluuje wyrażenie zerowe (patrz 11.5.4.8.2).Przedmioty inne niż false i zero są klasyfikowane jako obiekty prawdziwe. true jest jedynym wystąpieniem klasy
TrueClass
(patrz 15.2.5), do którego odnosi się wyrażenie prawdziwe (patrz 11.5.4.8.3).
Plik wykonywalny Ruby / Spec wydaje się zgadzać :
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
Według tych dwóch źródeł zakładam, że Regexp
są one również zgodne z prawdą , ale według moich testów nie są to:
if // then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are falsy'
Przetestowałem to na YARV 2.7.0-Preview1 , TruffleRuby 19.2.0.1 i JRuby 9.2.8.0 . Wszystkie trzy implementacje są ze sobą zgodne i nie zgadzają się ze Specyfikacją języka Ruby ISO i moją interpretacją Ruby / Spec.
Mówiąc dokładniej, Regexp
obiekty będące wynikiem oceny Regexp
literałów są fałszem , podczas gdy Regexp
obiekty, które są wynikiem jakiegoś innego wyrażenia, są prawdziwe :
r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
Czy to błąd lub pożądane zachowanie?
!!//
jest fałszywe, ale !!/r/
prawdziwe. Rzeczywiście dziwne.
!!/r/
produkuje false
dla mnie za pomocą (RVM) Ruby 2.4.1.
//
in if // then
jest interpretowany jako test (skrót do if //=~nil then
) (który zawsze jest fałszem bez względu na wzorzec), a nie jako instancja Regexp.
Regex.new("a")
jest prawdą.