Ruby 对“真”和“假”有一个普遍的看法。
Ruby确实有两个用于布尔对象的特定类,TrueClass
和FalseClass
,单例实例分别由特殊变量true
和表示false
。
然而,真假不限于这两个类的实例,这个概念是通用的,适用于 Ruby 中的每一个对象。每个对象要么为真,要么为假。规则非常简单。特别是,只有两个对象是虚假的:
nil
, 的单例实例NilClass
和false
, 的单例实例FalseClass
每一个其他对象都是真实的。这甚至包括在其他编程语言中被认为是虚假的对象,例如
这些规则是内置在语言中的,不是用户可定义的。没有to_bool
隐式转换或类似的东西。
这是来自ISO Ruby 语言规范的引用:
6.6 布尔值
对象被分类为真实对象或虚假对象。
只有false和nil是虚假对象。false是该类的唯一实例
FalseClass
(参见 15.2.6),false 表达式对其进行评估(参见 11.5.4.8.3)。nil是该类的唯一实例NilClass
(参见 15.2.4),nil 表达式对其求值(参见 11.5.4.8.2)。除了false和nil之外的对象被归类为 true 对象。true是类的唯一实例
TrueClass
(见 15.2.5),真表达式求值(见 11.5.4.8.3)。
it "considers a non-nil and non-boolean object in expression result as true" do if mock('x') 123 else 456 end.should == 123 end
根据这两个来源,我会假设Regexp
s 也是truthy,但根据我的测试,它们不是:
if // then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are falsy'
我在YARV 2.7.0-preview1、TruffleRuby 19.2.0.1和JRuby 9.2.8.0上对此进行了测试。所有三个实现都相互同意,但不同意 ISO Ruby 语言规范和我对 Ruby/Spec 的解释。
更准确地说,Regexp
作为评估Regexp
文字结果的对象是falsy,而Regexp
作为其他表达式结果的对象是truthy:
r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
这是一个错误,还是期望的行为?