I want to make a hook method which gets called everytime any function of a class gets called. I have tried method_added, but it executes only once at the time of class definition,
class Base def self.method_added(name) p "#{name.to_s.capitalize} Method's been called!!" end def a p "a called." end def b p "b called." end end t1 = Base.new t1.a t1.b t1.a t1.b Output: "A Method's been called!!" "B Method's been called!!" "a called." "b called." "a called." "b called."
but my requirement is that any function of a class that gets called anywhere in the program triggers the "method_called", hook method.
Expected Output: "A Method's been called!!" "a called." "B Method's been called!!" "b called." "A Method's been called!!" "a called." "B Method's been called!!" "b called."
If there is any defined existing hook method that works just the same, then please tell about it.
Thanks in advance..
Take a look at Kernel#set_trace_func. It lets you specify a proc which is invoked whenever an event (such as a method call) occurs.
class Base def a puts "in method a" end def b puts "in method b" end end set_trace_func proc { |event, file, line, id, binding, classname| # only interested in events of type 'call' (Ruby method calls) # see the docs for set_trace_func for other supported event types puts "#{classname} #{id} called" if event == 'call' } b = Base.new b.a b.b
Outputs:
Base a called in method a Base b called in method b
最佳答案:
class Base def self.method_added(name) if /hook/.match(name.to_s) or method_defined?("#{name}_without_hook") return end hook = "def #{name}_hook\n p 'Method #{name} has been called'\n #{name}_without_hook\nend" self.class_eval(hook) a1 = "alias #{name}_without_hook #{name}" self.class_eval(a1) a2 = "alias #{name} #{name}_hook" self.class_eval(a2) end def a p "a called." end def b p "b called." end end t1 = Base.new t1.a t1.b t1.a t1.b