这个问题的具体用例可能会引起github问题,但我的问题比你所看到的具体用例更广泛,所以请耐心等待!
我在项目中使用render_anywhere
gem,我发现需要撤销在下一次迭代发生之前在循环内设置的实例变量(使用{{的对象)的情况1}}存在于循环外部,因此变量保留在范围内。
我宁愿避免在可能的情况下为循环的每次迭代重新初始化对象。
set_instance_variable
方法的工作原理如下(摘自rubydoc):
# File 'lib/render_anywhere.rb', line 20
def set_instance_variable(var, value)
rendering_controller.class_eval do
attr_accessor :"#{var}"
end
rendering_controller.public_send("#{var}=", value)
end
所以我想我需要使用this answer中描述的方法中的某些内容删除attr_accessor
:
undef :"#{var}"
undef :"#{var}="
所以我的问题确实是双重的:
rendering_controller
删除属性读/写方法的最佳方法吗?attr_accessor
执行undef
无法清理的其他任何内容' 答案 0 :(得分:0)
attr_accessor
是一个“宏”,它只是为具有相同名称的ivar定义getter和setter方法:
# This line...
attr_accessor :hello
# ...is equivalent to these
def hello
@hello
end
def hello=(value)
@hello = value
end
因此,您需要撤消set_instance_variable
代码的效果:
var
var=
@var
参数value
醇>
请注意set_instance_variable
方法在控制器实例上下文中执行所有这些操作,而不是控制器类上下文(尽管令人困惑class_eval
)。
您必须执行以下操作才能撤消上述所有操作:
def unset_instance_variable(var)
rendering_controller.remove_instance_variable("@#{var}") if instance_variable_defined?("@#{var}")
rendering_controller.class_eval { remove_method(var) } if rendering_controller.respond_to?(var)
rendering_controller.class_eval { remove_method("#{var}=") } if rendering_controller.respond_to?("#{var}=")
end
如果您想避免猴子修补,请考虑将rendering_controller
作为参数发送此方法。