Ruby:在自定义方法

时间:2016-07-30 17:58:40

标签: ruby-on-rails ruby http request net-http

我尝试自定义记录http请求。我们的想法是定义一个记录请求的函数。

recorded :get, :post, :patch, :delete do
  Net::HTTP.get(URI('http://www.google.com')) #will log
end

Net::HTTP.get(URI('http://news.ycombinator.com')) # will not log

问题是我需要在alias_method类中Net::HTTP,并且不允许在方法内定义类。

这是方法定义。

require 'net/http'

def recorded(*methods, &block)
  # module Net
  #   class HTTP
  #     alias_method(:orig_request, :request) unless method_defined?(:orig_request)
  #     alias_method(:orig_connect, :connect) unless method_defined?(:orig_connect)
  #
  #     def request(req, body = nil, &block)
  #       if started?
  #         puts :started
  #       end
  #
  #       @response = orig_request(req, body, &block)
  #       puts @response.code
  #       # LOGGING HERE THE REQUEST
  #
  #       @response
  #     end
  #
  #     def connect
  #       orig_connect
  #     end
  #   end
  # end

  yield block
end

1 个答案:

答案 0 :(得分:0)

当你克服这个特殊问题时,你会立即遇到很多其他问题,但回答了这个问题: alias_method只是一种类方法

Net::HTTP.alias_method(:orig_request, :request)

以上将完美的工作。但是你的代码从来没有“ dealiases ”它(恢复原始方法),因此对Net::HTTP#request的任何后续调用将依次调用别名版本。< / p>

为了避免这种情况,可以在类Net::HTTP上设置一个实例变量,或类似,以保持状态和路由到别名方法或原始方法。

旁注:因为Ruby2我们为此目的Module#prepend,所以使用这样的别名方法看起来像遗产。