【问题标题】:Why does this method fail to instrument ActionView::Template :render?为什么此方法无法检测 ActionView::Template :render?
【发布时间】:2012-04-13 04:15:09
【问题描述】:

我们正在将 MiniProfiler 移植到 Ruby,并希望为 Rails 视图和局部视图添加自动检测。

我知道existing instrumentation 支持,但理想情况下希望获得“开始”和“停止”事件。我们还希望支持不支持通知的早期版本的 Rails。

我破解了一个简短的仪器并测试了使用 beforeafter 调用连接渲染:

def prof(klass, method)
  with_profiling = (method.to_s + "_with_profiling").intern
  without_profiling = (method.to_s + "_without_profiling").intern

  klass.send :alias_method, without_profiling, method
  klass.send :define_method, with_profiling do |*args, &orig|
    puts "before #{method} #{args}"
    self.send without_profiling, *args, &orig
    puts "after #{method}"
  end
  klass.send :alias_method, method, with_profiling
end

prof ActionView::Template, :render

但是,一旦激活 render 就无法正确检测。特别是这适用于某些部分,但会爆炸:

ActionView::Template::Error(nil:NilClass 的未定义方法 `html_safe')

这个方法钩子有什么问题?什么是钩子方法的适当健壮方法,以便它们不会受到这个问题的影响(维护微不足道的 API:prof klass, method

【问题讨论】:

  • 有任何理由支持(method.to_s + "_with_profiling").intern 而不是:"#{method}_with_profiling"

标签: ruby-on-rails ruby ruby-on-rails-3 metaprogramming mvc-mini-profiler


【解决方案1】:

您重新定义了返回最终puts 的结果的方法,通常为nil。解决方法可能是:

klass.send :define_method, with_profiling do |*args, &orig|
  puts "before #{method} #{args}"
  result = self.send without_profiling, *args, &rig
  puts "after #{method}"

  result
end

【讨论】:

  • 哇...不敢相信我错过了它,这将让我学会从 Ruby 中休息一下 :)
  • 现在我需要问的后续问题是如何从钩子中获得一个理智的视图名称
猜你喜欢
  • 2018-07-08
  • 1970-01-01
  • 2012-08-02
  • 2020-08-14
  • 2015-06-11
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
  • 1970-01-01
相关资源
最近更新 更多