Come verificare se un oggetto Ruby è un booleano


Risposte:


136

Il modo più semplice a cui posso pensare:

# checking whether foo is a boolean
!!foo == foo

6
classe X; def!; fine del sé; x = X.new; !! x == x # => true
Alexey

5
Sì, si chiama dattilografia e un principio fondamentale di OOP. Penso che sia una caratteristica.
Konstantin Haase

62
Breve non significa necessariamente semplice. Con questo intendo, che cos'è?
Grant Birchmeier

11
Trasforma foo in un booleano, controlla se è uguale a foo.
Konstantin Haase

9
Nota che la doppia negazione è considerata un cattivo stile da alcuni dama (come RuboCop ).
sschuberth

104

Trovo che questo sia conciso e auto-documentato:

[true, false].include? foo

Se utilizzi Rails o ActiveSupport, puoi anche eseguire una query diretta utilizzando in?

foo.in? [true, false]

Il controllo rispetto a tutti i valori possibili non è qualcosa che consiglierei per i float, ma fattibile quando ci sono solo due valori possibili!


1
la migliore risposta in assoluto, anche se mi è piaciuto anche foo == true or foo == falseche qualcuno abbia inserito un commento.
Ryan Taylor

3
Mi piace perché è meno criptico nell'intento del file !!foo == foo.
stringsn88keys

Decisamente pitonico! Sicuramente la risposta più semantica qui di gran lunga.
JM Janzen

85

Non v'è alcuna Booleanclasse in Ruby, l'unico modo di controllo è quello di fare quello che stai facendo (confrontando l'oggetto contro truee falseo la classe dell'oggetto contro TrueClasse FalseClass). Non riesco a pensare al motivo per cui avresti bisogno di questa funzionalità, puoi spiegarmi? :)

Se hai davvero bisogno di questa funzionalità, tuttavia, puoi hackerarla in:

module Boolean; end
class TrueClass; include Boolean; end
class FalseClass; include Boolean; end

true.is_a?(Boolean) #=> true
false.is_a?(Boolean) #=> true

1
cercando di eseguire il typecasting in base al valore corrente.
Lance Pollard

75
"Perché mai cosa?" (e derivati) è solo una delle domande più fastidiose che un ingegnere possa farne a un'altra :)
vemv

11
+1 perché posso usarlo in rspec come:expect(some_method?(data)).to be_a(Boolean)
Automatico

3
Un altro caso in cui è necessario controllare il tipo, è quando si implementa l'adattatore del database e sono necessarie stringhe di wrapping con "quotes"ma non numeri e booleani
Daniel Garmoshka

23

Come affermato sopra non esiste una classe booleana solo TrueClass e FalseClass tuttavia puoi usare qualsiasi oggetto come soggetto di if / until e tutto è vero tranne le istanze di FalseClass e nil

I test booleani restituiscono un'istanza di FalseClass o TrueClass

(1 > 0).class #TrueClass

Il seguente monkeypatch su Object ti dirà se qualcosa è un'istanza di TrueClass o FalseClass

class Object
  def boolean?
    self.is_a?(TrueClass) || self.is_a?(FalseClass) 
  end
end

L'esecuzione di alcuni test con irb fornisce i seguenti risultati

?> "String".boolean?
=> false
>> 1.boolean?
=> false
>> Time.now.boolean?
=> false
>> nil.boolean?
=> false
>> true.boolean?
=> true
>> false.boolean?
=> true
>> (1 ==1).boolean?
=> true
>> (1 ==2).boolean?
=> true

4
Più semplice solo da scrivere self == true or self == false. Quelle sono le uniche istanze di TrueClass e FalseClass.
Chuck

@chuck che restituisce gli stessi risultati tranne Time.now.boolean? che restituisce zero. Qualche idea sul perché?
Steve Weet

Definire un controllo di classe su se stesso nel metodo non è in qualche modo oop. È necessario definire due versioni di boolean, una per TrueClass / FalseClass e una per Object.
Konstantin Haase

4
Il motivo è che un bug nella versione di Time#==in Ruby 1.8 fa sì che un confronto con i valori non Time restituisca zero anziché falso.
Chuck

17

Se il tuo codice può essere sensibilmente scritto come un'istruzione case, questo è abbastanza decente:

case mybool
when TrueClass, FalseClass
  puts "It's a bool!"
else
  puts "It's something else!"
end

6

Un oggetto che è un booleano avrà una classe TrueClass o FalseClass quindi il seguente one-liner dovrebbe fare il trucco

mybool = true
mybool.class == TrueClass || mybool.class == FalseClass
=> true

Quanto segue fornisce anche il risultato del controllo del tipo booleano vero / falso

mybool = true    
[TrueClass, FalseClass].include?(mybool.class)
=> true

4

Quindi prova questa (x == true) ^ (x == false)nota che ti serve la parentesi ma questa è più bella e compatta.

Passa anche il suggerito come "cuak" ma non un "cuak" ... class X; def !; self end end ; x = X.new; (x == true) ^ (x == false)

Nota : guarda che questo è così semplice che puoi usarlo anche in altre lingue, che non fornisce un "cosa è booleano".

Nota 2 : puoi anche usare questo per dire che cosa è uno di ??:"red", "green", "blue"se tuadd more XORS... o dici che questa cosa è uno di ??:4, 5, 8, 35.


Perché XOR? Perché no?
Nakilon


0

No. Non come se avessi il tuo codice. Non esiste alcuna classe denominata Boolean. Ora con tutte le risposte che hai dovresti essere in grado di crearne una e usarla. Sai come creare classi, vero? Sono venuto qui solo perché mi stavo chiedendo questa idea io stesso. Molte persone potrebbero dire "Perché? Devi solo sapere come Ruby usa Boolean". Ecco perché hai ottenuto le risposte che hai fatto. Quindi grazie per la domanda. Cibo per la mente. Perché Ruby non ha una classe booleana?

NameError: uninitialized constant Boolean

Tieni presente che gli oggetti non hanno tipi. Sono classi. Gli oggetti contengono dati. Ecco perché quando dici tipi di dati è un termine improprio.

Prova anche rand 2 perché rand 1 sembra sempre dare 0. rand 2 darà 1 o 0 clic eseguiti alcune volte qui. https://repl.it/IOPx/7

Anche se non saprei come fare io stesso a fare un corso booleano. L'ho sperimentato ma ...

class Boolean < TrueClass
  self
end

true.is_a?(Boolean) # => false
false.is_a?(Boolean) # => false

Almeno ora abbiamo quella classe, ma chi sa come ottenere i valori giusti?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.