How do you extend a Ruby module with macro-like metaprogramming methods?

Posted by Ian Terrell on Stack Overflow See other posts from Stack Overflow or by Ian Terrell
Published on 2010-06-10T22:16:06Z Indexed on 2010/06/10 22:22 UTC
Read the original article Hit count: 177

Filed under:
|
|

Consider the following extension (the pattern popularized by several Rails plugins over the years):

module Extension
  def self.included(recipient)
    recipient.extend ClassMethods
    recipient.class_eval { include InstanceMethods }
  end

  module ClassMethods
    def macro_method
      puts "Called macro_method within #{self.name}"
    end
  end

  module InstanceMethods
    def instance_method
      puts "Called instance_method within #{self.object_id}"
    end
  end
end

If you wished to expose this to every class, you can do the following:

Object.send :include, Extension

Now you can define any class and use the macro method:

class FooClass
  macro_method
end
#=> Called macro_method within FooClass

And instances can use the instance methods:

FooClass.new.instance_method
#=> Called instance_method within 2148182320

But even though Module.is_a?(Object), you cannot use the macro method in a module:

module FooModule
  macro_method
end
#=> undefined local variable or method `macro_method' for FooModule:Module (NameError)

This is true even if you explicitly include the original Extension into Module with Module.send(:include, Extension).

How do you add macro like methods to Ruby modules?

© Stack Overflow or respective owner

Related posts about ruby

Related posts about metaprogramming