Module: ModuleCreationHelper::Extensions::Module

Defined in:
lib/module_creation_helper/extensions/module.rb

Overview

Adds helper methods for easily generating new modules/classes

Instance Method Summary collapse

Instance Method Details

#create(name, options = {}, &block) ⇒ Object

Creates a new module with the specified name. This is essentially the same as actually defining the module like so:

module NewModule
end

or as a class:

class NewClass < SuperKlass
end

Configuration options:

  • :superclass - The class to inherit from. This only applies when using Class#create. Default is Object.

  • :parent - The class/module that contains this module. Default is Object.

Examples

Module.create('Foo')                                                      # => Foo
Module.create('Bar', :parent => Foo)                                      # => Foo::Bar
Class.create('Waddle')                                                    # => Waddle
Class.create('Widdle', :parent => Waddle)                                 # => Waddle::Widdle
Class.create('Woddle', :superclass => Waddle::Widdle, :parent => Waddle)  # => Waddle::Woddle
Waddle::Woddle.superclass                                                 # => Waddle::Widdle

Setting the parent

Rather than setting the parent directly using the parent configuration option, you can specify it in the actual name of the class like so:

Module.create('Foo::Bar')   # => Foo::Bar

This has the same effect as the following:

Module.create('Bar', :parent => Foo)

Raises:

  • (ArgumentError)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/module_creation_helper/extensions/module.rb', line 41

def create(name, options = {}, &block)
  # Validate the provided options
  invalid_options = options.keys - [:superclass, :parent]
  raise ArgumentError, "Unknown key(s): #{invalid_options.join(", ")}" unless invalid_options.empty?
  
  # Validate usage of :superclass option
  raise ArgumentError, 'Modules cannot have superclasses' if options[:superclass] && self.to_s == 'Module'
  
  options = {:superclass => Object, :parent => Object}.merge(options)
  parent = options[:parent]
  superclass = options[:superclass]
  
  if superclass != Object
    superclass = " < ::#{superclass}"
  else
    superclass = ''
  end
  
  mod = parent.class_eval <<-end_eval
    #{self.to_s.downcase} #{name}#{superclass}
      self
    end
  end_eval
  
  mod.class_eval(&block) if block_given?
  mod
end