Ruby 3.2.2升级后创建Null Binding触发RuntimeError求助
Ruby 3.2.2 下 NullBinding 报错的解决方案
问题原因
Ruby 3.2.0 开始对 Kernel#binding 的调用逻辑做了严格限制:当尝试将 binding 方法绑定到非Ruby核心实现的对象(比如继承自 BasicObject 的类实例)时,会抛出 RuntimeError: Cannot create Binding object for non-Ruby caller 错误。你之前基于 BasicObject 实现的 NullBinding 正好触发了这个新检查。
修复方案
改用普通 Object 实例创建最小化的绑定上下文,既保留“空环境”的需求,又符合Ruby 3.2+ 的规则:
方案1:重构 NullBinding 类
class NullBinding # 直接返回空Object实例的binding def self.min_binding Object.new.instance_eval { binding } end end class Whatever def self.evaluate(string) eval string, NullBinding.min_binding, __FILE__, __LINE__ end end
方案2:简化代码(无需额外类)
如果不需要单独维护 NullBinding 类,可以直接在 evaluate 方法内生成空绑定:
class Whatever def self.evaluate(string) # 创建空Object实例并获取其binding empty_binding = Object.new.instance_eval { binding } eval string, empty_binding, __FILE__, __LINE__ end end
效果验证
调用原测试代码:
self.class.evaluate "->(a, b) { [b.last_modified, b.date] <=> [a.last_modified, a.date] }"
此时不会再触发报错,且绑定上下文依然保持干净(无额外实例变量、无多余方法),符合原 NullBinding 的设计意图。
内容的提问来源于stack exchange,提问作者Mike Slinn
相关产品推荐
相关产品推荐

