You can get a callback on any method being created with Module#method_added, alias the old method, then define a new method that calls the before_filter method first. Here's my (extremely) rough first concept:
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
By using __method__
like you were in create_prefix
, you'll get the name of the filter method, not the original method, so you have to pass the method name in. There might be other solutions to make that a bit cleaner.