简体   繁体   中英

How to dynamically define all instance methods of class in module?

I want to prepend (or include ) some module into the class . This module should dynamically define all the instance methods defined in that class with some customisation. Is that possible ?

Something like this

   Module M
     klass_methods = get_instance_methods_of(classname) 
     // get_instance_methods_of is available to me.
     // So, getting the methods is not a  problem. 
     // But i have to pass class name


     klass_methods.each do |m|
        define_method m do
          puts "from module"
          super
        end
     end
   end

  Class C
    prepend M
    def some
       puts "from class"
    end
  end

$ C.new.some
>> from module
>> from class

possible?

In case you want to know more what i was trying to do, you can read here https://github.com/elabs/pundit/issues/244

I'm using Ruby ruby 2.1.3p242 with RoR

Here is a solution based on this answer:

module M
  def method_added(meth)
    return if @recursing
    @recursing = true
    old_meth = instance_method(meth)
    define_method(meth) do |*args, &block|
      puts 'from module'
      old_meth.bind(self).call(*args, &block)
    end
    @recursing = nil
  end
end

class C
  extend M
  def some
    puts "from class"
  end
end

C.new.some
# from module
# from class

This solution uses the method_added hook to intercept new methods in the extended class, and then re-defining them with the aspect oriented code.

Be aware that only methods which are declared after the extend M line would be intercepted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM