如何解耦功能和登录ruby方法

时间:2017-04-17 13:10:50

标签: ruby-on-rails ruby

我喜欢记录很多。在我的Rails应用程序中,我有很多方法,如:

def my_method(argument1:, argument2:)
  logger.info "Starting my_method with arguments: #{argument1} and #{argument2}"
  result = argument1 + argument2
  logger.info "Finished my_method with result: #{result}"
end

如何解除方法的功能和日志记录?

理想情况下,结果看起来像这样(从Rails中借用回调概念就是一个例子):

before_method: :my_method_log_start, only: :my_method
after_method: :my_method_log_end, only: :my_method

def my_method(argument1:, argument2:)
  result = argument1 + argument2
end

private

def my_method_log_start
  logger.info "Starting my_method with arguments: #{argument1} and #{argument2}"
end

def my_method_log_end
  logger.info "Finished my_method with result: #{result}"
end

我知道这在代码行方面效率较低,而且更具可读性(在我看来)。

我已经阅读了Aspect Orient Programming以及他们的一些宝石,比如Aquarius,但看起来像是一种过度杀戮来为日志记录添加新的范例。

3 个答案:

答案 0 :(得分:3)

我认为Avdi Grimm对您可以使用的技术有很好的解释。我们的想法是将日志记录(或其他任何内容)提取到侦听器类并将事件发布到该侦听器,基本示例将是

class Task
  # ...
  def add_listener(listener)
    (@listeners ||= []) << listener
  end
  # ...

  def notify_listeners(event_name, *args)
    @listeners && @listeners.each do |listener|
      if listener.respond_to?(event_name)
        listener.public_send(event_name, self, *args)
      end
    end
  end 
end

并且喜欢

task = Task.new
task.add_lestener(YourLoggerClass.new)
task.notify_listeners(:start_logging)
task.notify_listeners(:end_logging)

答案 1 :(得分:2)

如果这仅用于本地调试,那么$.ajax({ type:"GET", url:"https://example.com"+"?"+$.param(myObj); contentType:"application/json", data:{}, success:function(data){ } });类是一个很好的用例。这是代码:

TracePoint

我建议阅读本课程的文档,它有非常好的功能。当然,您需要稍微优化一下这些代码来处理一些边缘情况。您可以添加一些过滤器,仅为您关心的方法调用跟踪块。或者您可以根据代码的某些部分启用/禁用此功能。

答案 2 :(得分:0)

您可以通过它的名称调用方法,或将其转换为proc并传递给另一个方法。所以你可以这样写:     

def foo(a, b)
  a + b
end

def call_with_logging(method_name, *args)
  args_as_string = args.map(&:to_s).join(' ')
  puts "Starting my_method with arguments #{args_as_string}"
  result = Object.send(method_name, *args)
  puts "Finished my_method with result: #{result}"
end

call_with_logging :foo, 1, 2