TrueClass
和FalseClass
,由特殊变量true
和false
分别表示其单例实例。然而,“真值”和“假值”不仅限于这两个类的实例,这个概念是“普遍的”,适用于Ruby中的每个对象。每个对象都是“真值”或“假值”。规则非常简单。特别地,“只有两个对象是假值”:-
nil
,NilClass
的单例实例和
- false
,FalseClass
的单例实例“每一个其他的对象”都是“真值”。这甚至包括在其他编程语言中被认为是“假值”的对象。
这些规则是编程语言内置的,不可由用户定义。没有类似于to_bool
的隐式转换。
以下是ISO Ruby Language Specification中的一句话:
6.6 布尔值
一个对象被归类为真对象或假对象。
只有false和nil是假对象。 false是类FalseClass
的唯一实例(见15.2.6),其中包含一个假表达式 (见11.5.4.8.3)。 nil是类NilClass
的唯一实例(见15.2.4),其中包含一个nil表达式 (见11.5.4.8.2)。
除了false和nil之外的对象都被归类为真对象。 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
也是真值,但是根据我的测试,它们并不是: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
对象是 falsy,而由于其他表达式而产生的 Regexp
对象是 truthy。r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
这是一个bug还是期望的行为?
!!//
是假的,但!!/r/
是真的。确实很奇怪。 - maxif // then
中的//
被解释为一个测试(if //=~nil then
的快捷方式)(无论模式如何始终为假),而不是作为一个正则表达式实例。 - Casimir et Hippolyteif //
将会像 cli 用法一样作用于$_
.. 例如:seq 10 15 | ruby -ne 'print if /[35]/'
和seq 10 15 | ruby -ne 'print if $_ =~ /[35]/'
是相同的。 - Sundeep!!/r/ #=> false
,但前缀的!
实际上是BasicObject#!
的语法糖,因此写成/r/.!.!
,无论$_
设置为什么,都将返回true
,这与 Ruby 的预期相符。 - Travis