【发布时间】:2018-10-02 16:03:06
【问题描述】:
我正在编写旧代码 Rails 3、Ruby 1.9.3 代码库。我引用了一个由于各种原因无法升级的 gem。 gem 已经使用 class_eval 进行了猴子修补(正确的术语?)。我需要对另一种看起来像这样的方法进行更改:
SomeNamespace::Bar do
def some_method
@@part_of_header ||= JSON.dump({... Stuff ...})
# ... other code ...
headers = {
"Header Part" => @@part_of_header
#... other headers ...
}
end
end
@@part_of_header 类变量背后的想法是缓存 JSON 转储以便可以重复使用。 @@part_of_header 没有在 Bar 基类的其他地方定义。
我的猴子补丁方法如下:
SomeNamespace::Bar.class_eval do
def some_method
@@part_of_header ||= JSON.dump({... Stuff ...})
# ... other code that I changed ...
headers = {
"Header Part" => @@part_of_header
#... other headers that I changed ...
}
end
end
代码工作正常,但我在 @@part_of_header 类变量的行中收到以下警告:
Class variable access from toplevel
我尝试将类变量移动到它自己的方法:
SomeNamespace::Bar.class_eval do
def header_part
@@part_of_header ||= JSON.dump({... Stuff ...})
end
def some_method
# ... other code that I changed ...
headers = {
"Header Part" => header_part
#... other headers that I changed ...
}
end
end
但是,“顶级”错误刚刚移至 header_part 方法。
我也尝试使用 class_variable_set 和 class_variable_get 访问类变量,但出现未定义的方法错误。
关于如何解决此警告的任何建议?如果无法修复关于在 class_eval 中缓存 JSON 转储的任何建议?谢谢。
更新: 感谢 @Josh 将完整的类名与 class_variable_get/set 一起使用。我的最终解决方案如下:
SomeNamespace::Bar.class_eval do
def header_part
# Create the class variable if it does not exist, remember
# the base class does not define @@part_of_header.
if !SomeNamesapce::Bar.class_variable_defined?(:@@part_of_header)
SomeNamespace::Bar.class_variable_set(:@@part_of_header, nil)
end
if (SomeNamespace::Bar.class_variable_get(:@@part_of_header).nil?
header_part = JSON.dump({... Stuff ...})
SomeNamespace::Bar.class_variable_set(:@@part_of_header, header_part)
end
SomeNamespace::Bar.class_variable_get(:@@part_of_header)
end
def some_method
# ... other code that I changed ...
headers = {
"Header Part" => header_part
#... other headers that I changed ...
}
end
end
上述工作,但对上述解决方案的任何反馈将不胜感激。谢谢。
【问题讨论】: