我正在阅读《制作 Rails 应用程序》这本书,并获得了 Rails 源代码。在那里我发现了一些让我思考的 RUBY_EVAL 示例:他们为什么要这样做?
action_controller/metal/renderers.rb 使用它来组成 _write_render_options 的主体并定义 _handle_render_options 方法。
def _write_render_options
renderers = _renderers.map do |name, value|
<<-RUBY_EVAL
if options.key?(:#{name})
_process_options(options)
return _render_option_#{name}(options.delete(:#{name}), options)
end
RUBY_EVAL
end
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def _handle_render_options(options)
#{renderers.join}
end
RUBY_EVAL
end
_render_option_#{name} 方法也是动态定义的
RENDERERS = {}
def self.add(key, &block)
define_method("_render_option_#{key}", &block)
RENDERERS[key] = block
All._write_render_options
end
在我看来,eval 有其他选择。为什么不将那些与键关联的 &blocks 保留在哈希下?那么当调用 _handle_render_options 时,我们会选择正确的块并评估它吗?为什么要构建一个包含大量 if 的方法体,这是低效的,对吧?
还没拿到