Ruby: automatically wrapping methods in event triggers

后端 未结 1 1186
独厮守ぢ
独厮守ぢ 2021-01-14 22:08

Heres what I have/want:

module Observable
  def observers; @observers; end

  def trigger(event, *args)
    good = true
    return good unless (@observers ||         


        
相关标签:
1条回答
  • 2021-01-14 22:50

    There are a several ways to do it with the help of metaprogramming magic. For example, you can define a method like this:

    def override_public_methods(c)
      c.instance_methods(false).each do |m|
        m = m.to_sym
        c.class_eval %Q{
          alias #{m}_original #{m}
          def #{m}(*args, &block)
            puts "Foo"
            result = #{m}_original(*args, &block)
            puts "Bar"
            result
          end
        }
      end
    end
    
    class CustomBaseObject
      def test(a, &block)
        puts "Test: #{a}"
        yield
      end
    end
    
    override_public_methods(CustomBaseObject)
    
    foo = CustomBaseObject.new
    foo.test(2) { puts 'Block!' }
    # => Foo
         Test: 2
         Block!
         Bar
    

    In this case, you figure out all the required methods defined in the class by using instance_methods and then override them.

    Another way is to use so-called 'hook' methods:

    module Overrideable
      def self.included(c)
        c.instance_methods(false).each do |m|
          m = m.to_sym
          c.class_eval %Q{
            alias #{m}_original #{m}
            def #{m}(*args, &block)
              puts "Foo"
              result = #{m}_original(*args, &block)
              puts "Bar"
              result
            end
          }
        end
      end
    end
    
    class CustomBaseObject
      def test(a, &block)
        puts "Test: #{a}"
        yield
      end
    
      include Overrideable
    end
    

    The included hook, defined in this module, is called when you include that module. This requires that you include the module at the end of the class definition, because included should know about all the already defined methods. I think it's rather ugly :)

    0 讨论(0)
提交回复
热议问题