Home > Back-end >  How to access class method from the included hook of a Ruby module
How to access class method from the included hook of a Ruby module

Time:04-09

I'd like my module to define new instance methods based on its including class' instance methods. But in the included hook, the class methods are not defined yet (as the module is included at the top of the class, before the class methods are defined):

module MyModule
    def self.included(includer)
        puts includer.instance_methods.include? :my_class_method # false <- Problem
    end
end

class MyClass
    include MyModule
    def my_class_method
    end
end

I want the users of the module to be free to include it at the top of their class.

Is there a way to make a module define additional methods to a class?

Note: I don't have to use the included hook if there is another way to achieve this.

CodePudding user response:

There'a a method_added callback you could use:

module MyModule
  def self.included(includer)
    def includer.method_added(name)
      puts "Method added #{name.inspect}"
    end
  end
end

class MyClass
  include MyModule

  def foo ; end
end

Output:

Method added :foo

If you want to track both, existing and future methods, you might need something like this:

module MyModule
  def self.on_method(name)
    puts "Method #{name.inspect}"
  end

  def self.included(includer)
    includer.instance_methods(false).each do |name|
      on_method(name)
    end

    def includer.method_added(name)
      MyModule.on_method(name)
    end
  end
end

Example:

class MyClass
  def foo ; end

  include MyModule

  def bar; end
end

# Method :foo
# Method :bar
  • Related