Class: Toys::Utils::ModuleLookup

Inherits:
Object
  • Object
show all
Defined in:
lib/toys/utils/module_lookup.rb

Overview

A helper module that provides methods to do module lookups. This is used to obtain named helpers, middleware, and templates from the respective modules.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeModuleLookup

Create an empty ModuleLookup



86
87
88
# File 'lib/toys/utils/module_lookup.rb', line 86

def initialize
  @paths = []
end

Class Method Details

.path_to_module(path) ⇒ Module

Given a require path, return the module expected to be defined.

Parameters:

  • path (String)

    File path, delimited by forward slash

Returns:

  • (Module)

    The module loaded from that path



72
73
74
75
76
77
78
79
80
# File 'lib/toys/utils/module_lookup.rb', line 72

def path_to_module(path)
  path.split("/").reduce(::Object) do |running_mod, seg|
    mod_name = to_module_name(seg)
    unless running_mod.constants.include?(mod_name)
      raise ::NameError, "Module #{running_mod.name}::#{mod_name} not found"
    end
    running_mod.const_get(mod_name)
  end
end

.to_module_name(str) ⇒ Symbol

Convert the given string to a module name. Specifically, converts to UpperCamelCase, and then to a symbol.

Parameters:

  • str (String, Symbol)

    String to convert.

Returns:

  • (Symbol)

    Converted name



61
62
63
64
# File 'lib/toys/utils/module_lookup.rb', line 61

def to_module_name(str)
  str = str.to_s.sub(/^_/, "").sub(/_$/, "").gsub(/_+/, "_")
  str.to_s.gsub(/(^|_)([a-zA-Z])/) { |_m| $2.upcase }.to_sym
end

.to_path_name(str) ⇒ String

Convert the given string to a path element. Specifically, converts to lower_snake_case.

Parameters:

  • str (String, Symbol)

    String to convert.

Returns:

  • (String)

    Converted string



48
49
50
51
52
# File 'lib/toys/utils/module_lookup.rb', line 48

def to_path_name(str)
  str = str.to_s.sub(/^_/, "").sub(/_$/, "").gsub(/_+/, "_")
  while str.sub!(/([^_])([A-Z])/, "\\1_\\2") do end
  str.downcase
end

Instance Method Details

#add_path(path_base, module_base: nil, high_priority: false) ⇒ Object

Add a lookup path for modules.

Parameters:

  • path_base (String)

    The base require path

  • module_base (Module) (defaults to: nil)

    The base module, or nil (the default) to infer a default from the path base.

  • high_priority (Boolean) (defaults to: false)

    If true, add to the head of the lookup path, otherwise add to the end.



99
100
101
102
103
104
105
106
107
# File 'lib/toys/utils/module_lookup.rb', line 99

def add_path(path_base, module_base: nil, high_priority: false)
  module_base ||= ModuleLookup.path_to_module(path_base)
  if high_priority
    @paths.unshift([path_base, module_base])
  else
    @paths << [path_base, module_base]
  end
  self
end

#lookup(name) ⇒ Module

Obtain a named module. Returns nil if the name is not present.

Parameters:

  • name (String, Symbol)

    The name of the module to return.

Returns:

  • (Module)

    The specified module



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/toys/utils/module_lookup.rb', line 116

def lookup(name)
  @paths.each do |path_base, module_base|
    path = "#{path_base}/#{ModuleLookup.to_path_name(name)}"
    begin
      require path
    rescue ::LoadError
      next
    end
    mod_name = ModuleLookup.to_module_name(name)
    unless module_base.constants.include?(mod_name)
      raise ::NameError,
            "File #{path.inspect} did not define #{module_base.name}::#{mod_name}"
    end
    return module_base.const_get(mod_name)
  end
  nil
end