在Ruby中如何为Regexp#~一元前缀运算符设置别名支持`hit /needle/`调用
解决方案
要实现hit /needle/和~ /needle/行为完全一致,核心问题是要拿到调用hit方法的上下文里的$_变量值,以下是可直接运行的标准实现(适用于Ruby 2.5及以上版本):
module Kernel def hit(pattern) # 获取调用方上下文,读取对应作用域的$_变量 pattern =~ binding.caller(1, 1)[0].eval('$_') end end
效果验证
可以通过以下代码确认两者行为完全一致:
# 给当前作用域的$_赋值 $_ = "test string contains needle" # 原生~运算符返回结果 p ~/needle/ # => 21 # 自定义hit方法返回结果 p hit /needle/ # => 21
原方案失效原因说明
- 第一种给
Regexp类加hit别名的方案,仅能支持/pattern/.hit这种实例方法调用形式。你写hit /pattern/时,Ruby会尝试在当前上下文(比如main对象)查找hit方法,而非在正则实例上调用,因此会报NoMethodError。 - 第二种在
Object类定义方法的方案,方法内部直接读取的$_是该方法自身作用域内的局部值,默认永远为nil,无法继承调用方的$_取值。
内容的提问来源于stack exchange,提问作者psychoslave
相关产品推荐
相关产品推荐

