Comment vérifier si un objet Ruby est un booléen


Réponses:


136

Le moyen le plus simple auquel je puisse penser:

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

6
classe X; def!; fin de soi; x = X.new; !! x == x # => true
Alexey

5
Oui, cela s'appelle le typage canard et un principe de base de la POO. Je pense que c'est une fonctionnalité.
Konstantin Haase

62
Court ne veut pas nécessairement dire simple. Par quoi je veux dire, qu'est-ce que c'est?
Grant Birchmeier

11
Transforme foo en booléen, vérifie si c'est la même chose que foo.
Konstantin Haase

9
Notez que la double négation est considérée comme un mauvais style par certains contrôleurs (comme RuboCop ).
sschuberth

104

Je trouve cela concis et auto-documenté:

[true, false].include? foo

Si vous utilisez Rails ou ActiveSupport, vous pouvez même effectuer une requête directe en utilisant in?

foo.in? [true, false]

La vérification par rapport à toutes les valeurs possibles n'est pas quelque chose que je recommande pour les flottants, mais c'est faisable lorsqu'il n'y a que deux valeurs possibles!


1
meilleure réponse de loin, même si j'ai aussi aimé foo == true or foo == falseque quelqu'un mette un commentaire.
Ryan Taylor

3
J'aime cela parce que son intention est moins cryptique que le !!foo == foo.
stringsn88keys

Franchement pythonique! Certainement la réponse la plus sémantique ici de loin.
JM Janzen

85

Il n'y a pas de Booleanclasse dans Ruby, la seule façon de vérifier est de faire ce que vous faites (comparer l'objet avec trueet falseou la classe de l'objet avec TrueClassetFalseClass ). Vous ne savez pas pourquoi vous auriez besoin de cette fonctionnalité, pouvez-vous expliquer? :)

Si vous avez vraiment besoin de cette fonctionnalité, vous pouvez la pirater dans:

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

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

1
essayer de faire du typage en fonction de la valeur actuelle.
Lance Pollard

75
«Pourquoi as-tu jamais fait ça? (et ses dérivés) n'est qu'une des questions les plus ennuyeuses qu'un ingénieur puisse en poser :)
vemv

11
+1 parce que je peux utiliser ceci dans rspec comme:expect(some_method?(data)).to be_a(Boolean)
Automatico

3
Un autre cas où vous devez vérifier le type, c'est lorsque vous implémentez un adaptateur de base de données et que vous avez besoin de chaînes enveloppantes avec "quotes"mais pas de nombres et de booléens
Daniel Garmoshka

23

Comme indiqué ci-dessus, il n'y a pas de classe booléenne juste TrueClass et FalseClass, mais vous pouvez utiliser n'importe quel objet comme sujet de if / sauf et tout est vrai sauf les instances de FalseClass et nil

Les tests booléens retournent une instance de FalseClass ou TrueClass

(1 > 0).class #TrueClass

Le monkeypatch suivant à Object vous dira si quelque chose est une instance de TrueClass ou FalseClass

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

L'exécution de certains tests avec irb donne les résultats suivants

?> "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
Plus simple à écrire self == true or self == false. Ce sont les seules instances de TrueClass et FalseClass.
Chuck

@chuck qui renvoie les mêmes résultats sauf pour Time.now.boolean? qui renvoie nul. Une idée pourquoi?
Steve Weet

Définir un contrôle de classe sur soi dans la méthode n'est pas quelque chose de bon. Vous devez définir deux versions de boolean, une pour TrueClass / FalseClass et une pour Object.
Konstantin Haase

4
La raison en est qu'un bogue dans la version de Time#==dans Ruby 1.8 fait qu'une comparaison avec des valeurs non-Time renvoie nil plutôt que faux.
Chuck

17

Si votre code peut raisonnablement être écrit comme une déclaration de cas, c'est assez décent:

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

6

Un objet qui est un booléen aura soit une classe de TrueClass ou FalseClass donc le one-liner suivant devrait faire l'affaire

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

Ce qui suit vous donnera également un résultat de vérification de type booléen vrai / faux

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

4

Alors essayez cette (x == true) ^ (x == false)note, vous avez besoin de la parenthèse mais c'est plus beau et compact.

Il passe même le suggéré comme "cuak" mais pas un "cuak" ... class X; def !; self end end ; x = X.new; (x == true) ^ (x == false)

Remarque : voyez que c'est tellement basique que vous pouvez aussi l'utiliser dans d'autres langues, cela ne fournit pas de "chose est booléenne".

Note 2 : Vous pouvez également utiliser ceci pour dire que la chose est l'une des ??: "red", "green", "blue"si vous add more XORS... ou dites que cette chose est l'une des ??: 4, 5, 8, 35.


Pourquoi XOR? Pourquoi pas OU?
Nakilon


0

Non, pas comme si vous aviez votre code. Il n'y a aucune classe nommée Boolean. Maintenant, avec toutes les réponses que vous avez, vous devriez pouvoir en créer une et l'utiliser. Vous savez comment créer des classes, n'est-ce pas? Je ne suis venu ici que parce que je me demandais moi-même cette idée. Beaucoup de gens pourraient dire "Pourquoi? Vous devez simplement savoir comment Ruby utilise Boolean". C'est pourquoi vous avez obtenu les réponses que vous avez faites. Alors merci pour la question. Nourriture pour la pensée. Pourquoi Ruby n'a-t-il pas de classe booléenne?

NameError: uninitialized constant Boolean

Gardez à l'esprit que les objets n'ont pas de types. Ce sont des classes. Les objets ont des données. C'est pourquoi, lorsque vous dites les types de données, c'est un peu un abus de langage.

Essayez aussi rand 2 car rand 1 semble toujours donner 0. rand 2 donnera 1 ou 0 clic plusieurs fois ici. https://repl.it/IOPx/7

Bien que je ne sache pas comment faire moi-même une classe booléenne. Je l'ai expérimenté mais ...

class Boolean < TrueClass
  self
end

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

Au moins, nous avons cette classe maintenant, mais qui sait comment obtenir les bonnes valeurs?

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.