module Modulation::Exports

Functionality related to symbol export

Constants

CONST_INSPECT_CODE
NOT_FOUND_MSG

Public Class Methods

define_const_inspect_methods(mod, sym, value) click to toggle source
# File lib/modulation/exports.rb, line 149
def define_const_inspect_methods(mod, sym, value)
  if value.method(:inspect).source_location.nil?
    code = format(CONST_INSPECT_CODE, mod.inspect, sym)
    value.singleton_class.module_eval(code)
  end
end
export(mod, *symbols) click to toggle source
# File lib/modulation/exports.rb, line 25
def export(mod, *symbols)
  case symbols.first
  when Hash
    symbols = export_hash(mod, symbols.first)
  when Array
    symbols = symbols.first
  end

  validate_exported_symbols(mod, symbols)
  symbols
end
export_directive(mod, directive) click to toggle source
# File lib/modulation/exports.rb, line 19
def export_directive(mod, directive)
  send directive[:method], mod, *directive[:args]
rescue NameError => e
  Modulation.raise_error e, directive[:export_caller]
end
export_from_receiver(mod, name) click to toggle source
# File lib/modulation/exports.rb, line 37
def export_from_receiver(mod, name)
  if name !~ Modulation::RE_CONST
    raise 'export_from_receiver expects a const reference'
  end

  ExportFromReceiver.from_const(mod, name)
end
export_hash(mod, hash) click to toggle source

@return [Array] array of exported symbols

# File lib/modulation/exports.rb, line 65
def export_hash(mod, hash)
  singleton = mod.singleton_class
  hash.each { |k, v| export_hash_entry(singleton, k, v) }
  hash.keys
end
export_hash_entry(singleton, key, value) click to toggle source
# File lib/modulation/exports.rb, line 71
def export_hash_entry(singleton, key, value)
  symbol_value = value.is_a?(Symbol)
  const_value = value =~ Modulation::RE_CONST
  if value && const_value && singleton.const_defined?(value)
    value = singleton.const_get(value)
  end

  generate_exported_hash_entry(singleton, key, value, symbol_value)
end
expose_exported_constants(mod, singleton, symbols) click to toggle source

Copies exported constants from singleton to module @param mod [Module] module with exported symbols @param singleton [Class] sinleton for module @param symbols [Array] array of exported symbols @return [void]

# File lib/modulation/exports.rb, line 122
def expose_exported_constants(mod, singleton, symbols)
  defined_constants = singleton.constants(false)
  process_module_constants(mod, singleton, symbols, defined_constants)
end
generate_exported_hash_entry(singleton, key, value, symbol_value) click to toggle source
# File lib/modulation/exports.rb, line 81
def generate_exported_hash_entry(singleton, key, value, symbol_value)
  const_key = key =~ Modulation::RE_CONST
  if const_key
    singleton.const_set(key, value)
  elsif symbol_value && singleton.method_defined?(value)
    singleton.alias_method(key, value)
  else
    value_proc = value.is_a?(Proc) ? value : proc { value }
    singleton.send(:define_method, key, &value_proc)
  end
end
perform_exports(mod) click to toggle source

Performs the exporting of symbols after the module has loaded

# File lib/modulation/exports.rb, line 10
def perform_exports(mod)
  directives = mod.__export_directives
  exported_symbols = directives.inject [] do |exported, directive|
    symbols = export_directive mod, directive
    exported + symbols
  end
  set_exported_symbols mod, exported_symbols
end
privatize_non_exported_methods(singleton, symbols) click to toggle source

Sets all non-exported methods as private for given module @param singleton [Class] sinleton for module @param symbols [Array] array of exported symbols @return [void]

# File lib/modulation/exports.rb, line 109
def privatize_non_exported_methods(singleton, symbols)
  singleton.instance_methods(false).each do |sym|
    next if symbols.include?(sym)

    singleton.send(:private, sym)
  end
end
process_module_constants(mod, singleton, symbols, defined_constants) click to toggle source
# File lib/modulation/exports.rb, line 127
def process_module_constants(mod, singleton, symbols, defined_constants)
  private_constants = mod.__module_info[:private_constants] = []
  defined_constants.each do |sym|
    next if sym == :MODULE

    value = singleton.const_get(sym)
    define_const_inspect_methods(mod, sym, value) if value.is_a?(Module)

    if symbols.include?(sym)
      mod.const_set(sym, value)
    else
      private_constants << sym
    end
  end
end
raise_exported_symbol_not_found_error(sym, kind) click to toggle source
# File lib/modulation/exports.rb, line 158
def raise_exported_symbol_not_found_error(sym, kind)
  msg = format(
    NOT_FOUND_MSG, kind == :method ? 'Method' : 'Constant', sym
  )
  raise NameError, msg
end
set_exported_symbols(mod, symbols) click to toggle source

Marks all non-exported methods as private, exposes exported constants @param mod [Module] module with exported symbols @param symbols [Array] array of exported symbols @return [void]

# File lib/modulation/exports.rb, line 97
def set_exported_symbols(mod, symbols)
  mod.__module_info[:exported_symbols] = symbols
  singleton = mod.singleton_class

  privatize_non_exported_methods(singleton, symbols)
  expose_exported_constants(mod, singleton, symbols)
end
validate_exported_symbol(sym, list, kind) click to toggle source
# File lib/modulation/exports.rb, line 58
def validate_exported_symbol(sym, list, kind)
  return if list.include? sym

  raise_exported_symbol_not_found_error(sym, kind)
end
validate_exported_symbols(mod, symbols) click to toggle source
# File lib/modulation/exports.rb, line 45
def validate_exported_symbols(mod, symbols)
  defined_methods = mod.singleton_class.instance_methods(true)
  defined_constants = mod.singleton_class.constants(false)

  symbols.each do |sym|
    if sym =~ Modulation::RE_CONST
      validate_exported_symbol(sym, defined_constants, :const)
    else
      validate_exported_symbol(sym, defined_methods, :method)
    end
  end
end