使用元编程将方法包围在类中 [英] use metaprogramming to surround methods in a class
问题描述
我有一些带有方法的类,它们会在进入和退出方法时进行记录,如下所示:
def methodName1(args)
@logger.debug(">>#{callee}")
...
@logger.debug("<<#{callee}")
end
I have classes with methods that log when a method is entered and exited like so:
def methodName1(args)
@logger.debug(">>#{callee}")
...
@logger.debug("<<#{callee}")
end
def methodName2(args) @logger.debug(">>#{callee}") ... @logger.debug("<<#{callee}") end
def methodName2(args) @logger.debug(">>#{callee}") ... @logger.debug("<<#{callee}") end
我想知道是否有一个元编程方法将这些方法与logger调用一起使用? 这将涉及到确定我要首先包围的类中的所有方法,然后再包围它们.
I was wondering if there was a metaprogramming way to surround the methods with the logger calls? It would involve identifying all the methods in a class that I want surrounded first and then surrounding them.
A
推荐答案
我认为此解决方案应有所帮助:
i guess this solution should help:
class Foo
def initialize
(self.methods - Object.methods).each do |method|
# we need to make alias for method
self.class.send(:alias_method, "#{method}_without_callback", method)
# save method params, and destroy old method
params = self.method(method).parameters.map(&:last).join(',')
self.class.send(:undef_method, method)
# creating new method with old name, and pass params to this
eval("
self.class.send(:define_method, method) do |#{params}|
puts 'Call_before'
self.send('#{method}_without_callback', #{params})
puts 'Call_after'
end
")
end
end
def say_without_param
puts "Hello!"
end
def say_hi(par1)
puts "Hi, #{par1}"
end
def say_good_bye(par1, par2)
puts "Good bye, #{par1} #{par2}"
end
end
因此,当我们创建对象时,初始化后将创建别名方法,销毁旧方法,并创建带有call_backs的新方法;
So when we create an object, after initialization there will be created alias methods, destroyed old methods, and new methods with call_backs will be created;
用法示例:
obj = Foo.new
obj.say_without_param # => Call_before
Hello!
Call_after
obj.say_hi('Johny') # => Call_before
Hi, Johny
Call_after
obj.say_good_bye('mr.', 'Smith') => Call_before
Good bye, mr. Smith
Call_after
这篇关于使用元编程将方法包围在类中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!