Rubyオブジェクトがブール値かどうかを確認する方法


122

オブジェクトがブール値であるかどうかを簡単に確認できないようです。Rubyにこのようなものはありますか?

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

今私はこれをやっていて、短くしたいと思います:

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

回答:


136

私が考えることができる最も簡単な方法:

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

6
クラスX; def!; セルフエンドエンド; x = X.new; !! x == x#=> true
Alexey

5
はい、それはダックタイピングと呼ばれ、OOPのコア原則です。機能だと思います。
Konstantin Haase

62
ショートとは、必ずしも単純であるとは限らない。つまり、wtfはそれですか。
Grant Birchmeier

11
fooをブール値に変換し、それがfooと同じかどうかを確認します。
Konstantin Haase 2013

9
一部のチェッカー(RuboCopなど)では、二重否定は不適切なスタイルと見なされています。
sschuberth

104

私はこれが簡潔で自己文書化されていると思います:

[true, false].include? foo

RailsまたはActiveSupportを使用している場合は、直接クエリを実行することもできます in?

foo.in? [true, false]

考えられるすべての値をチェックすることは、フロートに推奨されるものではありませんが、考えられる値が2つしかない場合は実行可能です。


1
答えは断然最高ですがfoo == true or foo == false、誰かがコメントを入れるのも好きです。
Ryan Taylor

3
私はこれが好きです。それは意図よりも不可解ではないから!!foo == fooです。
stringsn88keys 2017年

なんとパイソン!間違いなく、これまでで最もセマンティックな答えはここです。
JM Janzen

85

そこにはありませんBooleanクラスが(チェックする唯一の方法は何をやっているやっている、Rubyでオブジェクトに対して比較trueし、falseまたはに対するオブジェクトのクラスをTrueClassし、FalseClass)。なぜこの機能が必要になるのかわからないのですが、説明できますか?:)

ただし、この機能が本当に必要な場合は、次の方法でハッキングできます。

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

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

1
現在の値に基づいて型キャストを実行しようとしています。
Lance Pollard

75
「なんでそんなことするの?」(および派生物)は、エンジニアが別の質問をすることができる最も厄介な質問の1つにすぎません:)
vemv 2014年

11
1私は次のようにRSpecの中でこれを使用することができますので、:expect(some_method?(data)).to be_a(Boolean)
Automatico

3
タイプをチェックする必要がある他のケースは、データベースアダプターを実装し"quotes"、数字やブール値ではなく文字列をラップする必要がある場合です
Daniel Garmoshka

23

上記のとおり、ブールクラスはTrueClassとFalseClassだけではありませんが、任意のオブジェクトをif / unlessの対象として使用でき、FalseClassとnilのインスタンスを除いてすべてがtrueです。

ブールテストはFalseClassまたはTrueClassのインスタンスを返します

(1 > 0).class #TrueClass

Objectへの次のmonkeypatchは、何かがTrueClassまたはFalseClassのインスタンスであるかどうかを通知します

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

irbでいくつかのテストを実行すると、次の結果が得られます

?> "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
書くだけで簡単self == true or self == false。これらはTrueClassとFalseClassの唯一のインスタンスです。
Chuck

Time.now.booleanを除いて同じ結果を返す@chuck?これはnilを返します。なぜだと思いますか?
Steve Weet

メソッドで自分自身のクラスチェックを定義することは、いくらかうまくいきません。booleanTrueClass / FalseClass用とObject用の2つのバージョンを定義する必要があります。
Konstantin Haase

4
その理由は、バージョンのバグが Time#==、Ruby 1.8のにより、Time以外の値との比較でfalseではなくnilが返されるためです。
チャック

17

あなたのコードがケースステートメントとしてうまく書けるなら、これはかなりまともです:

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

6

ブール値のオブジェクトは、TrueClassまたはFalseClassのクラスを持つため、次のワンライナーでトリックを実行する必要があります

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

次の場合も、真/偽のブール型チェック結果が得られます

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

4

だからこれを試してみてください (x == true) ^ (x == false)あなたが括弧を必要とするメモしますが、これはより美しく、よりコンパクトです。

「cuak」のような提案は通過しますが、「cuak」は通過しません... class X; def !; self end end ; x = X.new; (x == true) ^ (x == false)

:これは非常に基本的であり、他の言語でも使用できるため、「ブール値」は提供されません。

注2:これを使用して、「ものは次のうちの1つである??:」と言うこと"red", "green", "blue"もできadd more XORSます4, 5, 8, 35


なぜXORなのか?なぜORではないのですか?
ナキロン


0

いいえ。コードを持っているようではありません。Booleanという名前のクラスはありません。これですべての回答が得られたので、作成して使用することができます。あなたはクラスを作成する方法を知っていますか?ここに来たのは、このアイデアを自分で考えていたからです。多くの人が「なぜ?Rubyがブール値を使用する方法を知っている必要がある」と言うかもしれません。あなたがした答えを得たのはそのためです。質問に感謝します。思考の糧。Rubyにブールクラスがないのはなぜですか?

NameError: uninitialized constant Boolean

オブジェクトにはタイプがないことに注意してください。彼らはクラスです。オブジェクトにはデータがあります。だから、データ型と言ったとき、それは少し誤称です。

また、rand 1は常に0を与えるため、rand 2も試してください。rand2は、ここで1回または0回のクリック実行を数回実行します。 https://repl.it/IOPx/7

私はブールクラスを自分で作る方法を知りませんが。私はそれを試しましたが...

class Boolean < TrueClass
  self
end

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

少なくとも今はそのクラスがありますが、正しい値を取得する方法を知っている人はいますか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.