2010-06-12 128 views
99

似乎无法找到如何检查对象是否容易布尔值。 Ruby中有这样的事情吗?检查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)) 
+0

相似:[检查是否变量是一个字符串在红宝石?](http://stackoverflow.com/questions/7749416/check-whether-a-variable-is-a- string-in-ruby?rq = 1) – nawfal 2014-07-24 01:58:52

回答

113

我能想到的最简单的方法:

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

class X; def!;自我结束; x = X.new; !! x == x#=> true – Alexey 2012-06-07 12:08:22

+5

是的,这就是所谓的鸭子打字和面向对象的核心原则。我认为这是一个功能。 – 2012-06-19 16:41:25

+1

问题在于“如果它像鸭子一样走路”并不意味着“它像鸭子一样嘎嘎”。相应地''pseudo_bool == pseudo_bool'并不意味着'pseudo_bool&true == pseudo_bool'例如。 – Alexey 2012-06-23 17:24:14

77

有Ruby中没有Boolean类,检查的唯一方法就是做你正在做什么(将对象与truefalse或对象的类别对照TrueClassFalseClass进行比较)。想不到为什么你会需要这个功能,你能解释一下吗? :)

如果你真的然而需要这个功能,你可以破解它:

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

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

尝试根据当前值进行类型转换。 – 2010-06-12 10:45:23

+57

'你为什么会这么做?' (和衍生产品)只是工程师可能做的另一个最令人讨厌的问题之一:) – vemv 2014-03-27 14:20:33

+9

+1,因为我可以在rspec中使用它,例如:expect(some_method?(data))to be_a(Boolean)' – Automatico 2014-10-14 15:56:07

19

如上所述没有Boolean类只是TrueClass和FalseClass但是你可以使用任何对象作为主题如果/除非一切都是真实的,除了FalseClass的实例和零

布尔测试返回FalseClass的实例或TrueClass

(1 > 0).class #TrueClass 

以下猴补丁到对象将告诉你什么是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或self == false'即可。这些是TrueClass和FalseClass的唯一实例。 – Chuck 2010-06-12 18:50:55

+0

@chuck返回除Time.now.boolean以外的相同结果吗?返回nil。任何想法为什么? – 2010-06-12 22:24:46

+0

在方法中定义对自身的类检查有点不符合要求。你应该定义两个'boolean'版本,一个用于TrueClass/FalseClass,一个用于Object。 – 2010-06-13 19:41:46

5

一个布尔对象将有一个类的TrueClass或FalseClass,所以下面的一行应该做的诱骗

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

下也能给你真/假布尔型检查结果

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

如果你的代码能够明智地写成一个case语句,这是相当不错的:

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

所以试试吧(x == true)^(x == false)注意你需要括号,但这更美观和紧凑。

它甚至还通过了建议,如“cuak”,但不是“cuak” ... class X; def !; self end end ; x = X.new; (x == true)^(x == false)

:看到这是如此基本,你可以在其他语言中使用过它,那不提供“东西是布尔”。

注2:您也可以使用此说的是??之一:"red", "green", "blue"如果你add more XORS ......或者说,这件事是??之一:4, 5, 8, 35

68

我觉得这是简洁和自我记录:

[true, false].include? foo 

如果使用Rails或的ActiveSupport,您可以使用in?

foo.in? [true, false] 

检查,对所有可能的值ISN连做直接查询我不推荐漂浮物,但只有两种可能的价值时才可行!

+0

最好的答案,虽然我也喜欢'foo == true或者foo == false',以便有人发表评论。 – 2016-06-10 20:53:56

+0

我喜欢这个,因为它比'!! foo == foo'更有意思。 – stringsn88keys 2017-11-14 19:38:32

0

不。不像你有你的代码。没有任何名为布尔的类。现在你有了所有的答案,你应该可以创建一个并使用它。你知道如何创建课程吗?我只是来到这里,因为我自己只是在想这个想法。许多人可能会说“为什么?你必须知道Ruby如何使用布尔值”。这就是为什么你得到了你所做的答案。所以谢谢你的问题。食物的思想。为什么Ruby没有布尔类?

NameError: uninitialized constant Boolean 

请记住,对象没有类型。他们是班级。对象有数据。所以这就是为什么当你说数据类型时,这有点不恰当。

也尝试兰特2,因为兰特1似乎总是给0.兰特2将给1或0 在这里点击运行几次。 https://repl.it/IOPx/7

虽然我不知道如何去做一个布尔类自己。我已经尝试过,但是...

class Boolean < TrueClass 
    self 
end 

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

至少我们现在有这个类,但谁知道如何获得正确的值?