【问题标题】:How to check if a Ruby object is a Boolean如何检查 Ruby 对象是否为布尔值
【发布时间】:2011-03-02 23:27:27
【问题描述】:

我似乎无法轻松检查对象是否为布尔值。 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))

【问题讨论】:

标签: ruby typechecking


【解决方案1】:

Ruby 中没有 Boolean 类,唯一的检查方法是做你正在做的事情(将对象与 truefalse 或对象的类与 TrueClass 和 @ 进行比较987654325@)。想不出你为什么需要这个功能,你能解释一下吗? :)

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

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

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

【讨论】:

  • 尝试根据当前值进行类型转换。
  • '你为什么要那样做?' (和衍生品)只是工程师可以提出的最烦人的问题之一 :)
  • +1 因为我可以在 rspec 中使用它,例如:expect(some_method?(data)).to be_a(Boolean)
  • 其他需要检查类型的情况是,当您实现数据库适配器并需要用"quotes" 而不是数字和布尔值包装字符串时
【解决方案2】:

如上所述,没有布尔类,只有 TrueClass 和 FalseClass,但是您可以使用任何对象作为 if/unless 的主题,并且除了 FalseClass 和 nil 的实例之外,一切都是真的

布尔测试返回 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

【讨论】:

  • self == true or self == false更简单。这些是 TrueClass 和 FalseClass 的唯一实例。
  • @chuck 返回除了 Time.now.boolean 之外的相同结果?返回零。知道为什么吗?
  • 在方法中定义对 self 的类检查有点不是 oop。您应该定义两个版本的boolean,一个用于 TrueClass/FalseClass,另一个用于 Object。
  • 原因是Ruby 1.8 中Time#== 版本中的一个错误导致与非时间值的比较返回nil 而不是false。
【解决方案3】:

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

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

【讨论】:

  • X 级;定义!;自我结束; x = X.新; !!x == x #=> 真
  • 是的,这就是所谓的鸭子类型,也是 OOP 的核心原则。我认为这是一个功能。
  • 短并不一定意味着简单。我的意思是,wtf是这样的吗?
  • 将 foo 转换为布尔值,检查是否与 foo 相同。
  • 请注意,双重否定被某些跳棋认为是不好的风格(如RuboCop)。
【解决方案4】:

一个布尔对象要么有一个 TrueClass 或 FalseClass 类,所以下面的单行应该可以解决问题

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

以下也会给你真/假布尔类型检查结果

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

【讨论】:

    【解决方案5】:

    如果你的代码可以合理地写成 case 语句,那就相当不错了:

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

    【讨论】:

      【解决方案6】:

      所以试试这个(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

      【讨论】:

      • 为什么要异或?为什么不做 OR?
      【解决方案7】:

      我认为这是简洁和自我记录的:

      [true, false].include? foo
      

      如果使用 Rails 或 ActiveSupport,您甚至可以使用 in? 进行直接查询

      foo.in? [true, false]
      

      我不建议对浮点数检查所有可能的值,但是当只有两个可能的值时是可行的!

      【讨论】:

      • 迄今为止最好的答案,虽然我也喜欢有人发表评论的foo == true or foo == false
      • 我喜欢这个,因为它的意图没有!!foo == foo那么神秘。
      • 彻头彻尾的pythonic!绝对是迄今为止最语义化的答案。
      【解决方案8】:

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

      NameError: uninitialized constant Boolean
      

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

      还可以尝试 rand 2,因为 rand 1 似乎总是给出 0。rand 2 会给出 1 或 0 单击此处运行几次。 https://repl.it/IOPx/7

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

      class Boolean < TrueClass
        self
      end
      
      true.is_a?(Boolean) # => false
      false.is_a?(Boolean) # => false
      

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

      【讨论】:

        【解决方案9】:

        这个 gem 用有用的方法向 Ruby 添加了一个布尔类。

        https://github.com/RISCfuture/boolean

        用途:

        require 'boolean'
        

        那么你的

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

        将完全按照您的预期工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-12-23
          • 2013-04-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-22
          • 2021-11-07
          相关资源
          最近更新 更多