动态扩展现有方法或覆盖ruby中的send方法

Har*_*ina 5 ruby metaprogramming

假设我们有A,B,C类.

A
 def self.inherited(sub)
   # meta programming goes here
   # take class that has just inherited class A
   # and for foo classes inject prepare_foo() as 
   # first line of method then run rest of the code
 end

 def prepare_foo
   # => prepare_foo() needed here
   # some code
 end

end

B < A
  def foo
    # some code
  end
end

C < A
  def foo
    # => prepare_foo() needed here
    # some code
  end
end
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我正在尝试foo_prepare()为每个foo()方法注入调用.

怎么办?

此外,我一直在考虑sendclass A这种方式覆盖类,我会运行,foo_prepare而不是让send(超级)继续执行该方法.

你们怎么想,解决这个问题的最佳方法是什么?

Ser*_*sev 7

这是一个适合您的解决方案.虽然它基于模块包含而不是从类继承,但我希望你仍然会发现它很有用.

module Parent
  def self.included child
    child.class_eval do
      def prepare_for_work
        puts "preparing to do some work"
      end

      # back up method's name
      alias_method :old_work, :work

      # replace the old method with a new version, which has 'prepare' injected
      def work
        prepare_for_work
        old_work
      end
    end
  end
end

class FirstChild
  def work
    puts "doing some work"
  end

  include Parent # include in the end of class, so that work method is already defined.
end

fc = FirstChild.new
fc.work
# >> preparing to do some work
# >> doing some work
Run Code Online (Sandbox Code Playgroud)