2010-06-12 16 views
99

Parece que no se puede encontrar cómo comprobar si un objeto es un booleano fácilmente. ¿Hay algo como esto en Ruby?Compruebe si el objeto Ruby es un booleano

true.is_a?(Boolean) 
false.is_a?(Boolean) 

En este momento estoy haciendo esto y me gustaría acortarla:

some_var = rand(1) == 1 ? true : false 
(some_var.is_a?(TrueClass) || some_var.is_a?(FalseClass)) 
+0

Similar: [check-if-a-variable-is-a-string-in-ruby?] (Http://stackoverflow.com/questions/7749416/check-whether-a-variable-is-a- string-in-ruby? rq = 1) – nawfal

Respuesta

113

manera más simple que puedo pensar:

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

clase X; def! extremo del uno mismo; x = X.new; !! x == x # => true – Alexey

+5

Sí, eso se llama tipado de pato y un principio básico de OOP. Creo que es una característica. –

+1

El problema es que "si camina como pato" no implica "cuartea como pato". De forma correspondiente '!! pseudo_bool == pseudo_bool' no implica' pseudo_bool & true == pseudo_bool' por ejemplo. – Alexey

77

no hay una clase Boolean en Ruby, la única manera de comprobar es hacer lo que está haciendo (comparando el objeto contra true y false o la clase del objeto contra TrueClass y FalseClass). Sin embargo, no puedo pensar en por qué necesitarías esta funcionalidad, ¿puedes explicarlo? :)

Si realmente necesita esta funcionalidad, sin embargo, se puede hackear en:

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

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

tratando de hacer typecasting basado en el valor actual. –

+57

'¿Por qué alguna vez qué es eso?' (y derivados) es solo una de las preguntas más molestas que puede hacer un ingeniero :) – vemv

+9

+1 porque puedo usar esto en rspec como: 'expect (some_method? (data)). to be_a (Boolean)' – Automatico

19

Como se ha señalado anteriormente no existe una clase booleana simplemente TrueClass y FalseClass sin embargo se puede utilizar cualquier objeto como el sujeto de si/menos y todo es cierto, excepto los casos de FalseClass y nula

pruebas booleanas devolver una instancia de la FalseClass o TrueClass

(1 > 0).class #TrueClass 

La siguiente monkeypatch a objeto le indicará si algo es una instancia de TrueClass o FalseClass

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

Ejecución de algunas pruebas con IRB da los siguientes resultados

?> "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

Más simple solo para escribir 'self == true o self == false'. Esas son las únicas instancias de TrueClass y FalseClass. – Chuck

+0

@chuck que devuelve los mismos resultados a excepción de Time.now.boolean? que devuelve nil. ¿Alguna idea de por qué? –

+0

La definición de una verificación de clase en self en el método no es algo oop. Debe definir dos versiones de 'boolean', una para TrueClass/FalseClass y otra para Object. –

5

Un objeto que es un booleano tendrá una clase de TrueClass o FalseClass, por lo que el siguiente delineador debe hacer el engañar

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

El siguiente sería también le dará verdadero/falso resultado de la comprobación de tipo booleano

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

Si su código con sensatez puede ser escrita como una declaración de caso, esto es bastante decente:

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

Así que pruebe esto (x == true)^(x == false) tenga en cuenta que necesita el paréntesis, pero esto es más hermoso y compacto.

Incluso se pasa la sugirió como "Cuak" pero no un "Cuak" ... class X; def !; self end end ; x = X.new; (x == true)^(x == false)

Nota: Ver que esto es tan básico que se puede usar en otros idiomas también, que no proporciona una "cosa es booleana".

Nota 2: También puede utilizar esto para decir que es uno de ??: "red", "green", "blue" si add more XORS ... o decir esto es una de ??: 4, 5, 8, 35.

68

me parece que esto sea conciso y auto-documentado:

[true, false].include? foo 

Si mediante rieles o ActiveSupport, incluso se puede hacer una consulta directa utilizando in?

foo.in? [true, false] 

Comprobación contra todos los valores posibles ISN Es algo que recomendaría para las carrozas, ¡pero factible cuando solo hay dos valores posibles!

+0

mejor respuesta, con mucho, aunque también me gustó' foo == true o foo == false' que alguien haya puesto un comentario. –

+0

Me gusta esto porque es menos críptico en intención que el '!! foo == foo'. – stringsn88keys

0

No, no como si tuviera su código. No hay ninguna clase llamada Boolean. Ahora, con todas las respuestas que tienes, deberías poder crear una y usarla. ¿Sabes cómo crear clases, verdad? Solo vine aquí porque me preguntaba esta idea yo mismo. Mucha gente podría decir "¿Por qué? Tienes que saber cómo Ruby usa Boolean". Por eso tienes las respuestas que obtuviste. Así que gracias por la pregunta. Comida para el pensamiento. ¿Por qué Ruby no tiene una clase booleana?

NameError: uninitialized constant Boolean 

Tenga en cuenta que los objetos no tienen tipos. Ellos son clases. Los objetos tienen datos. Entonces es por eso que cuando dices tipos de datos es un nombre inapropiado.

Pruebe también rand 2 porque rand 1 parece dar siempre 0. rand 2 dará 1 o 0 haga clic en ejecutar varias veces aquí. https://repl.it/IOPx/7

Aunque yo no sabría cómo hacer una clase booleana yo mismo. He experimentado con ella, pero ...

class Boolean < TrueClass 
    self 
end 

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

por lo menos tenemos esa clase, pero ahora que sabe cómo obtener los valores correctos?

Cuestiones relacionadas