如何访问通过class_exec()设置的Ruby类变量
Ruby类变量在class_exec中访问的问题解决方法
问题场景
尝试执行以下代码,在Ruby 3.2.1中运行时出现类变量访问错误:
class Foo; end Foo.class_exec do class_variable_set(:@@x, 42) def get @@x # 此处出现运行时错误! end end puts Foo.new.get
运行后报错信息:
$ ruby a.rb a.rb:6:in `get': class variable access from toplevel (RuntimeError) from a.rb:10:in `<main>'
问题:如何读取刚设置的@@x类变量?
原因解析
错误核心是作用域混淆:在class_exec块内定义实例方法时,直接使用@@x会被Ruby解析为尝试访问顶级作用域(main对象)的类变量,而非Foo类的类变量,因此抛出运行时错误。
解决方法
方法一:明确指定类对象获取类变量
在实例方法中通过self.class.class_variable_get方法,明确从当前实例所属的类中获取目标类变量:
class Foo; end Foo.class_exec do class_variable_set(:@@x, 42) def get self.class.class_variable_get(:@@x) end end puts Foo.new.get # 输出42
方法二:利用闭包捕获局部变量
在class_exec块内将类变量的值绑定到局部变量,再通过闭包让实例方法引用这个局部变量,绕开作用域解析问题:
class Foo; end Foo.class_exec do x = class_variable_set(:@@x, 42) define_method(:get) do x end end puts Foo.new.get # 输出42
内容的提问来源于stack exchange,提问作者yegor256
相关产品推荐
相关产品推荐

