module Builder

Implements creation of module instances

Private Class Methods

add_module_constants(mod, target, *symbols) click to toggle source

Adds all or part of a module's constants to a target object If no symbols are given, all constants are added @param mod [Module] imported module @param target [Object] object to add constants to @param symbols [Array<Symbol>] list of constants to add @return [void]

# File lib/modulation/builder.rb, line 131
def add_module_constants(mod, target, *symbols)
  exported = mod.__module_info[:exported_symbols]
  unless symbols.empty?
    symbols.select! { |s| s =~ Modulation::RE_CONST }
    exported = filter_exported_symbols(exported, symbols)
  end
  mod.singleton_class.constants(false).each do |sym|
    next unless exported.include?(sym)

    target.const_set(sym, mod.singleton_class.const_get(sym))
  end
end
add_module_methods(mod, target, *symbols) click to toggle source

Adds all or part of a module's methods to a target object If no symbols are given, all methods are added @param mod [Module] imported module @param target [Object] object to add methods to @param symbols [Array<Symbol>] list of methods to add @return [void]

# File lib/modulation/builder.rb, line 114
def add_module_methods(mod, target, *symbols)
  methods = mod.singleton_class.instance_methods(false)
  unless symbols.empty?
    symbols.select! { |s| s =~ /^[a-z]/ }
    methods = filter_exported_symbols(methods, symbols)
  end
  methods.each do |sym|
    target.send(:define_method, sym, &mod.method(sym))
  end
end
cleanup_module(mod) click to toggle source

Removes methods and constants from module @param mod [Module] module @return [void]

# File lib/modulation/builder.rb, line 97
def cleanup_module(mod)
  mod.constants(false).each { |c| mod.send(:remove_const, c) }
  singleton = mod.singleton_class
  undef_method = singleton.method(:undef_method)

  singleton.instance_methods(false).each(&undef_method)
  singleton.private_instance_methods(false).each(&undef_method)

  mod.__before_reload
end
create(info) click to toggle source

Initializes a new module ready to evaluate a file module @note The given block is used to pass the value given to `export_default` @param info [Hash] module info @return [Module] new module

# File lib/modulation/builder.rb, line 31
def create(info)
  Module.new.tap do |mod|
    mod.extend(ModuleMixin)
    mod.__module_info = info
    mod.singleton_class.const_set(:MODULE, mod)
  end
end
define_auto_import_const_missing_method(receiver, auto_import_hash) click to toggle source

Defines a const_missing method used for auto-importing on a given object @param receiver [Object] object to receive the const_missing method call @param auto_import_hash [Hash] a hash mapping constant names to a source

file and a caller location

@return [void]

Calls superclass method
# File lib/modulation/builder.rb, line 158
def define_auto_import_const_missing_method(receiver, auto_import_hash)
  receiver.singleton_class.send(:define_method, :const_missing) do |sym|
    (path, caller_location) = auto_import_hash[sym]
    path ? const_set(sym, import(path, caller_location)) : super(sym)
  end
end
filter_exported_symbols(exported, requested) click to toggle source
# File lib/modulation/builder.rb, line 144
def filter_exported_symbols(exported, requested)
  not_exported = requested - exported
  unless not_exported.empty?
    raise NameError, "symbol #{not_exported.first.inspect} not exported"
  end

  exported & requested
end
finalize_module_exports(info, mod) click to toggle source
# File lib/modulation/builder.rb, line 61
def finalize_module_exports(info, mod)
  if (default = mod.__export_default_info)
    ExportDefault.set_module_default_value(
      default[:value], info, mod, default[:caller]
    )
  else
    Exports.perform_exports(mod)
    if mod.respond_to?(:call) && !mod.respond_to?(:to_proc)
      def mod.to_proc
        method(:call).to_proc
      end
    end
  
    mod
  end
end
load_module_code(mod, info) click to toggle source

Loads a source file or a block into the given module @param mod [Module] module @param info [Hash] module info @return [void]

# File lib/modulation/builder.rb, line 56
def load_module_code(mod, info)
  path = info[:location]
  mod.instance_eval(info[:source] || IO.read(path), path || '(source)')
end
make(info) click to toggle source

Loads a module from file or block, wrapping it in a module facade @param info [Hash] module info @param block [Proc] module block @return [Class] module facade

# File lib/modulation/builder.rb, line 14
def make(info)
  # create module object
  mod = create(info)
  track_module_dependencies(mod) do
    # add module to loaded modules hash
    Modulation.loaded_modules[info[:location]] = mod

    load_module_code(mod, info)
    finalize_module_exports(info, mod)
  end
end
Also aliased as: orig_make
orig_make(info)
Alias for: make
reload_module_code(mod) click to toggle source

Loads code for a module being reloaded, turning warnings off in order to not generate warnings upon re-assignment of constants

# File lib/modulation/builder.rb, line 80
def reload_module_code(mod)
  orig_verbose = $VERBOSE
  $VERBOSE = nil
  prev_module = Thread.current[:__current_module]
  Thread.current[:__current_module] = mod

  cleanup_module(mod)
  load_module_code(mod, mod.__module_info)
  Exports.perform_exports(mod)
ensure
  Thread.current[:__current_module] = prev_module
  $VERBOSE = orig_verbose
end
track_module_dependencies(mod) { || ... } click to toggle source
# File lib/modulation/builder.rb, line 39
def track_module_dependencies(mod)
  prev_module = Thread.current[:__current_module]
  Thread.current[:__current_module] = mod

  if prev_module
    prev_module.__add_dependency(mod)
    mod.__add_dependent_module(prev_module)
  end
  yield
ensure
  Thread.current[:__current_module] = prev_module
end