RuboCop 多组 push/pop 后报 begin_pos,跳过配置生成的虚拟指令
RuboCop 多组局部指令可能使配置生成的虚拟指令进入源码位置检查。1.91.0 跳过此类对象,升级后应验证真实指令范围仍生效。
RuboCop 检查包含多组 push/pop 指令的文件时,可能在清理指令阶段报 begin_pos 的 NoMethodError。如果单组指令正常、多组才出错,要区分真实源码注释与工具内部生成的配置占位指令。
# .rubocop.yml
Metrics/MethodLength:
Enabled: false
原报告的局部指令形如下面这样,连续出现两组时发生崩溃:
# rubocop:push -Lint/UnusedMethodArgument
def lorem
nil
end
# rubocop:pop
# rubocop:push -Lint/UnusedMethodArgument
def ipsum
nil
end
# rubocop:pop
上面的配置片段用于理解全局关闭产生的虚拟指令,不是说原报告必须额外设置这个 Cop。先比较删除一组、保留两组的检查结果。不要在尚未定位前批量删除所有指令,它们可能控制其他仍启用的规则。
RuboCop 1.90.0 有这类崩溃案例。配置里关闭的 Cop,会在注释配置系统中表现为一种合成指令。这种对象不对应文件里真实的注释,因此不能按源码注释取范围位置。多个范围关闭、重新开启后,中间的有界范围进入了冗余指令检查,旧代码尝试从这个合成对象读取源码位置,最终失败。
RuboCop 1.91.0 包含明确的源身份判断:在处理冗余指令前跳过 ConfigDisabledCopDirectiveComment。修补点是识别配置产生的对象,不是改变 Ruby 源码注释的位置,也不要求重新排列真实的 push 和 pop。
调整现有版本约束后更新工具,并以原文件验证:
bundle update rubocop
bundle exec rubocop --version
bundle exec rubocop path/to/problem.rb
还不能升级时,可以暂时绕开引发崩溃的冗余指令检查,而不是关闭所有静态分析:
Lint/RedundantCopDisableDirective:
Enabled: false
这会减少对多余禁用指令的提示,因此应保留在临时配置中,升级验收后移除。文件中的局部禁用与全局关闭是否真的多余,要单独核对;删除它们属于代码策略调整,不能用来掩盖工具异常。
验收至少包含原来的多组指令文件、仅一组指令的对照文件,以及仍启用 Cop 的普通局部禁用。应确认工具完成检查,没有新的源码位置异常,同时真正需要的局部范围仍生效。此问题只说明合成配置指令被错误当成实体注释,其他 begin_pos 错误不能仅凭相同方法名归入同一个修补。


