regex - 为什么在 Ruby 中 Regexp 对象被认为是 "falsy"?

标签 regex ruby boolean jruby yarv

Ruby 对“真”和“假”有一个普遍的看法。

Ruby 确实有两个用于 boolean 对象的特定类 TrueClass FalseClass ,其单例实例分别由特殊变量 truefalse 表示。

然而,真假不限于这两个类的实例,这个概念是通用的,适用于 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 class NilClass (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-preview1TruffleRuby 19.2.0.1JRuby 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/

    相关文章:

    r - 除括号内的内容外,按空格拆分字符串

    javascript - 优化路径替换的正则表达式

    ruby-on-rails - bundle install --without production 有什么作用?

    java - 如何映射 url 中的项目列表 RequestMapping

    ruby - 将字符串转换为 ruby​​ 中的类名

    ruby - 如何连接条件

    java - Boolean 类的 getBoolean(String str) 和 valueOf(String str) 给出不同的输出

    java - boolean 引用

    Python:就地 "not' ing" boolean 值

    javascript - jquery/Javascript正则表达式过滤带逗号、13位int和2位小数的小数