Ruby/Rails:将代码添加到所有方法中 [英] Ruby/Rails: Prepend, append code to all methods

查看:34
本文介绍了Ruby/Rails:将代码添加到所有方法中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个小的基准测试类来测试我的代码进行开发.目前我必须将 Class 添加到每个方法的开头和结尾.是否可以预先添加、即时附加,这样我就不必弄乱我的代码?

I wrote a small benchmarking Class for testing my code doing development. At the moment I have to add the Class to the beginning and end of every method. Is it posible to prepend, append on the fly, so that I don't have to clutter my code?

class ApplicationController    
    before_filter :init_perf
    after_filter :write_perf_results_to_log!

    def init_perf
      @perf ||= Perf.new
    end

    def write_perf_results_to_log!
      @perf.results
    end
end

class Products < ApplicationsController    
    def foo      
      @perf.log(__methond__.to_s)
      caculation = 5 *4
      @perf.write! 
    end

    def bar      
      @perf.log(__methond__.to_s)
      caculation = 1 / 5
      @perf.write! 
    end
end

这是 Perf 类.它位于服务文件夹中.

This is the Perf class. It is located in the services folder.

class Perf
  def initialize
    @results = []
  end

  def log(note)
    @start = Time.now
    @note = note
  end

  def write!
    if @results.find {|h| h[:note] == @note } # Update :sec method exists in results 
      @results.select { |h| h["note"] == @note; h[":sec"] = (Time.now - @start).round(3) }
    else # Add new Hash to results
      @results << { :note => @note, :sec => (Time.now - @start).round(3) }
    end
  end

  def results
    content = "
    PERFORMANCE STATISTICS!
    "
    @results.each do |r|
      content += r[:note] + "   " + r[:sec].to_s + "
      "
    end
    content += "
    "
    Rails.logger.info content
  end
end

推荐答案

在一般的计算术语中,您想要执行的操作称为 代码检测.有几种方法可以实现这一点,但这里有一个使用元编程的(粗略)示例:

In general computing terms what you want to do is called code instrumentation. There are several ways to accomplish this, however here's one (crude) example using some metaprogramming:

首先定义一个我们将用于注入检测代码的新方法:

First define a new method that we will use for injecting our instrumentation code:

class ApplicationController
  def self.instrument_methods(*methods)
    methods.each { |m|
      # Rename original method
      self.send(:alias_method, "#{m}_orig", m)

      # Redefine old method with instrumentation code added
      define_method m do
        puts "Perf log #{m}"
        self.send "#{m}_orig"
        puts "Perf write"
      end
    }
  end
end

使用方法:

class Product < ApplicationController
  def foo
    puts "Foo"
  end

  def bar
    puts "Bar"
  end

  # This has to be called last, once the original methods are defined
  instrument_methods :foo, :bar
end

那么:

p = Product.new
p.foo
p.bar

将输出:

Perf log foo
Foo
Perf write
Perf log bar
Bar
Perf write

以下是检测 ruby​​ 代码和衡量性能的其他一些方法:

Here are some other ways to instrument ruby code and measure performance:

http://ruby-prof.rubyforge.org/
http://www.igvita.com/2009/06/13/profiling-ruby-with-googles-perftools/

这篇关于Ruby/Rails:将代码添加到所有方法中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆