include statement only allows for one type of argument: the module
constant(s) to include. Oftentimes I wish it would be possible to pass
arguments that the included module receives as optional parameters to its
included callback like so:
Module#included is the method that gets called when the module is included somewhere. Unlike in my would-be-nice example, it only receives one argument: the constant of the including class.
Additional arguments to
include are expected to be modules, allowing you to
include more than one module on one line.
A way to parameterize the behaviour of included modules is to add a singleton method in the included class and then have that class method accept parameters to do whatever (e.g. set class-wide variables or dynamically define methods).
This is obviously a contrived example, but what I dislike about it is the two
lines of meta programming that serve the same purpose: dynamically adding
something to the including class. Also, the
define_greeter class method is
probably not needed anywhere else in the class and this is against my sense of
Now, how about dynamically creating a module and then including that one?
Like … a module factory? How do we even start? It’s actually quite easy: the
include statement only accepts arguments of type
Module. So all we have to
make sure that whatever we pass to
include returns a proper Ruby
I give you this:
ModuleFactory.new(…) returns a module which can be included, thus
combining the include statement with the dynamic meta-programming. The provided
examples are all a bit abstract but I will provide a more concrete (Rails 5!)
example in a follow-up post.