将Ruby的匹配运算符应用于nil
的预期行为是什么?具体来说,捕获变量应该发生什么,为什么?
这段代码
"a1c" =~ /.*(d).*/
puts $1
nil =~ /.*(d).*/
puts $1
puts $1.nil?
产生如下结果:
1
1
false
我的理解是,失败的匹配将所有捕获变量重置为nil
。如果是这样,为什么$1
在尝试匹配nil
后仍然是1 ?
(我试图找到解释预期行为的文档;但是,我的谷歌技能失败了。)
NilClass#=~
的关键在于它不会失败。它总是返回nil
。
引用自文档:
nil =~ other → nil
虚拟模式匹配-总是返回nil。
查看其源代码,该方法非常简单,除了返回nil
:
static VALUE
nil_match(VALUE obj1, VALUE obj2)
{
return Qnil;
}
Ruby问题跟踪器中的对话可能也与此上下文相关。
In Ruby <3.2.0,NilClass#=~
实际上是由它的父类Object
在Object#=~
中实现的。这是一个回退方法,可以被Object
的子类覆盖,比如String
或Regexp
。Object#=~
方法在Ruby 2.6.0中被弃用,最终在Ruby 3.2.0中被删除。这些版本直接实现了NilClass#=~
。
基本Object#=~
参数。NilClass#=~
方法本身不执行匹配,而只是返回nil
,而不设置/重置任何全局魔术变量。这样做的效果是,该方法对所有对象都可用,但只对实现了重写方法的对象执行有意义的操作。