【发布时间】:2023-04-05 22:17:01
【问题描述】:
Ruby 对“truthiness”和“falsiness”有一个普遍的想法。
Ruby确实有两个特定的布尔对象类,TrueClass 和 FalseClass,单例实例分别由特殊变量 true 和 false 表示。
然而,truthiness 和 falsiness 不限于这两个类的实例,这个概念是通用的,适用于红宝石。每个对象要么是真实的,要么是虚假的。规则非常简单。特别是,只有两个对象是假的:
-
nil,NilClass和 的单例实例
-
false,FalseClass的单例实例
每一个其他的对象都是真实的。这甚至包括在其他编程语言中被视为 falsy 的对象,例如
这些规则内置于语言中,用户无法定义。没有to_bool 隐式转换或类似的东西。
这是ISO Ruby Language Specification的引述:
6.6 布尔值
对象分为真实对象或虚假对象。
只有 false 和 nil 是虚假对象。 false 是类
FalseClass的唯一实例(参见 15.2.6),false-expression 对其求值(参见 11.5.4.8.3)。 nil 是类NilClass的唯一实例(参见 15.2.4),nil 表达式对其求值(参见 11.5.4.8.2)。 p>false 和 nil 以外的对象被归类为真实对象。 true 是类
TrueClass的唯一实例(参见 15.2.5),true-expression 对其求值(参见 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
根据这两个来源,我认为Regexps 也是真实,但根据我的测试,它们不是:
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 literals 的结果是 falsy,而 Regexp 对象是一些其他表达式的结果是真相:
r = //
if r then 'Regexps are truthy' else 'Regexps are falsy' end
#=> 'Regexps are truthy'
这是一个错误,还是期望的行为?
【问题讨论】:
-
有趣的是
Regex.new("a")是真的。 -
!!//为假,但!!/r/为真。确实很奇怪。 -
@max
!!/r/使用 (RVM) Ruby 2.4.1 为我生成false。 -
对不起@3limin4t0r。你说的对。我一定是做了一些非常愚蠢的事情,比如漏掉了一个感叹号。
-
一个假设,我认为
if // then中的//被解释为测试(if //=~nil then的快捷方式)(无论模式如何,它总是错误的)而不是正则表达式实例。
标签: regex ruby boolean jruby yarv