我在所有课程中都使用了一个记录器。 我希望每个msg都以类名和方法名开头,如下所示:
Class_name::Method_name
这就是我现在正在做的事情:
class FOO
def initialize
end
def bar
msg_prefix = "#{self.class}::#{__method__}"
... some code ...
@logeer = "#{msg_prefix} msg ..."
end
def bar2
msg_prefix = "#{self.class}::#{__method__}"
... some code 2 ...
@logeer = "#{msg_prefix} msg2 ..."
end
end
我想在rails中使用before_filter来防止两面性,
我使用的是sinatra
,但这些类是普通的ruby 1.9.3
类
想法?
答案 0 :(得分:7)
您可以使用Module#method_added创建任何方法的回调,将旧方法作为别名,然后定义一个先调用before_filter方法的新方法。这是我(非常)粗略的第一个概念:
module Filter
def before_filter name
@@filter = name
end
def method_added name
return if @filtering # Don't add filters to original_ methods
return if @@filter == name # Don't filter filters
return if name == :initialize
@filtering = true
alias_method :"original_#{name}", name
define_method name do |*args|
self.send @@filter, name
self.send :"original_#{name}", *args
end
@filtering = false
end
end
class FilterTest
extend Filter
before_filter :prepare_logs
def baz
puts "#{@msg_prefix} message goes here"
end
def prepare_logs name
@msg_prefix = "#{self.class}::#{name}"
end
end
ft = FilterTest.new
ft.baz
通过__method__
使用create_prefix
,您将获得过滤方法的名称,而不是原始方法,因此您必须传入方法名称。可能还有其他名称解决方案让它更清洁。
答案 1 :(得分:2)
你可以使用ActiveModel::Callbacks获得before_filter
- 就像普通Ruby类中的行为一样(尽管在你的情况下,只执行一行就太过分了):
require 'active_model'
class FOO
extend ActiveModel::Callbacks
define_model_callbacks :baz, only: :before
before_baz :create_prefix
def initialize
end
def bar
run_callbacks :baz do
... some code ...
@logeer = "#{@msg_prefix} msg ..."
end
end
def bar2
run_callbacks :baz do
... some code 2 ...
@logeer = "#{@msg_prefix} msg2 ..."
end
end
private
def create_prefix
@msg_prefix = "#{self.class}::#{__method__}"
end
end