Defining “method_called”.. How do I make a hook method which gets called every time any function of a class gets called?

前端 未结 3 1355
北海茫月
北海茫月 2020-12-23 23:43

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 defin

3条回答
  •  滥情空心
    2020-12-24 00:09

    method_added is there to run code when a new method has been added to the class; it doesn't report when a method has been called. (As you discovered.)

    If you don't want to follow mikej's answer, here is a class that implements your specification:

    #!/usr/bin/ruby
    
    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
    

    And output:

    $ ./meta.rb
    "Method a has been called"
    "a called."
    "Method b has been called"
    "b called."
    "Method a has been called"
    "a called."
    "Method b has been called"
    "b called."
    

提交回复
热议问题