Consider the following extension (the pattern popularized by several Rails plugins over the years):
module Extension
def self.included(recipient)
recipient.extend ClassMethods
recipient.send :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)
.
For individual modules you can include extensions by hand and get the same effect:
module FooModule
include Extension
macro_method
end
#=> Called macro_method within FooModule
But how do you add macro-like methods to all Ruby modules?