Ruby ha un'idea universale di " verità " e " falsità ".
Rubino ha avere due classi specifiche per oggetti booleana, TrueClass
e FalseClass
, con istanze singleton denotati dalle variabili speciali true
e false
, rispettivamente.
Tuttavia, la verità e la falsità non si limitano ai casi di quelle due classi, il concetto è universale e si applica a ogni singolo oggetto in Ruby. Ogni oggetto è o verità o falsità . Le regole sono molto semplici. In particolare, solo due oggetti sono falsi :
nil
, l'istanza singleton diNilClass
efalse
, l'istanza singleton diFalseClass
Ogni singolo altro oggetto è veritiero . Ciò include anche oggetti considerati falsi in altri linguaggi di programmazione, come ad esempio
Queste regole sono integrate nella lingua e non sono definibili dall'utente. Non c'è to_bool
conversione implicita o qualcosa di simile.
Ecco una citazione dalla specifica ISO Ruby Language :
6.6 Valori booleani
Un oggetto è classificato in un oggetto trueish o in un oggetto false .
Solo false e zero sono oggetti falsi. false è l'unica istanza della classe
FalseClass
(vedi 15.2.6), alla quale valuta una falsa espressione (vedi 11.5.4.8.3). nil è l'unica istanza della classeNilClass
(vedi 15.2.4), a cui valuta un'espressione nil (vedi 11.5.4.8.2).Gli oggetti diversi da false e zero sono classificati in oggetti trueish. true è l'unica istanza della classe
TrueClass
(vedi 15.2.5), alla quale valuta un'espressione vera (vedi 11.5.4.8.3).
L'eseguibile Ruby / Spec sembra essere d'accordo :
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
Secondo queste due fonti, suppongo che anche le Regexp
s siano vere , ma secondo i miei test non lo sono:
if // then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are falsy'
Ho provato questo su YARV 2.7.0-preview1 , TruffleRuby 19.2.0.1 e JRuby 9.2.8.0 . Tutte e tre le implementazioni sono in accordo tra loro e non sono d'accordo con la specifica ISO Ruby Language e la mia interpretazione del Ruby / Spec.
Più precisamente, gli Regexp
oggetti che sono il risultato della valutazione dei Regexp
valori letterali sono falsi , mentre gli Regexp
oggetti che sono il risultato di un'altra espressione sono veri :
r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
È un bug o un comportamento desiderato?
!!//
è falso ma !!/r/
è vero. Davvero strano.
!!/r/
produce false
per me utilizzando (RVM) Ruby 2.4.1.
//
in if // then
sia interpretato come un test (una scorciatoia per if //=~nil then
) (che è sempre falsa qualunque sia il modello) e non come un'istanza Regexp.
Regex.new("a")
è vero.