Dynamic Module Snippet for Ruby

If you like making dynamic modules (the kind where you can do include MyModule.with_argument('foo')), then these 6 lines of code make writing them more convenient. You can write them like this:

require 'dynamic_module'

module MyModuleMaker
  extend DynamicModule

  module_function

  def make_module(arg)
    dynamic_module("ModuleForArg#{arg}") {
      # module code, where you can use the arg
    }
  end
end

Now you can include it like this:

class MyClass
  include MyModuleMaker.make_module('Foo')
end

It will produce MyModuleMaker::ModuleForArgFoo and include it.

If you include it again with the same arg, it will return the existing const.

Here’s the full snippet:

# A convenient way to build dynamic modules while caching them.
#
# Usage:
#
# require 'dynamic_module'
#
# module MyModuleMaker
#   extend DynamicModule
#
#   module_function
#
#   def make_module(arg)
#     dynamic_module("ModuleForArg#{arg}") {
#       # module code goes here
#     }
#   end
# end
#
# class MyClass
#   include MyModuleMaker.make_module('Foo')
# end
#
# When you run this include, you will get a new module named
# MyModuleMaker::ModuleForArgFoo. The next time include happens it will reuse
# the existing module.
module DynamicModule
  def dynamic_module(const_name, &block)
    return const_get(const_name) if const_defined?(const_name)
    const_set const_name, Module.new(&block)
  end
end

Code snippets in this post are covered by 0BSD License.


Tags
ruby snippet

Date
June 12, 2024