Ruby 对“真”和“假”有一个普遍的看法。
Ruby 确实有两个用于 boolean 对象的特定类 TrueClass
和 FalseClass
,其单例实例分别由特殊变量 true
和 false
表示。
然而,真假不限于这两个类的实例,这个概念是通用的,适用于 Ruby 中的每一个对象。每个对象要么是真,要么是假。规则非常简单。特别是,只有两个对象是虚假的:
nil
, NilClass
和 false
, FalseClass
的单例实例 其他每一个对象都是真实的。这甚至包括在其他编程语言中被认为是虚假的对象,例如
Integer
0
,Float
0.0
,String
''
,Array
[]
,Hash
{}
,这些规则是内置在语言中的,不是用户可定义的。没有
to_bool
隐式转换或类似的东西。这是 ISO Ruby Language Specification 的引述:
6.6 Boolean values
An object is classified into either a trueish object or a falseish object.
Only false and nil are falseish objects. false is the only instance of the class
FalseClass
(see 15.2.6), to which a false-expression evaluates (see 11.5.4.8.3). nil is the only instance of the classNilClass
(see 15.2.4), to which a nil-expression evaluates (see 11.5.4.8.2).Objects other than false and nil are classified into trueish objects. true is the only instance of the class
TrueClass
(see 15.2.5), to which a true-expression evaluates (see 11.5.4.8.3).
The executable Ruby/Spec seems to agree:
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
也是真实的,但根据我的测试,它们不是: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
对象是虚假的,而作为其他表达式结果的 Regexp
对象是真实的:r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
这是一个错误,还是期望的行为?
最佳答案
这不是错误。正在发生的事情是 Ruby 正在重写代码,以便
if /foo/
whatever
end
有效地变成
if /foo/ =~ $_
whatever
end
如果您在普通脚本中运行此代码(而不是使用
-e
选项),那么您应该会看到一个警告:warning: regex literal in condition
大多数时候这可能有点令人困惑,这就是给出警告的原因,但对于使用
-e
的一行可能很有用。选项。例如,您可以打印文件中与给定正则表达式匹配的所有行$ ruby -ne 'print if /foo/' filename
(
print
的默认参数也是 $_
。)
关于regex - 为什么在 Ruby 中 Regexp 对象被认为是 "falsy"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58340585/