Class: AwesomeLoader::ModuleBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/awesome_loader/module_builder.rb

Overview

Recursively builds modules out of directory structures.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root_depth:, root_module: Object) ⇒ ModuleBuilder

Initializes a new builder.

Parameters:

  • root_depth (Integer)

    directory depth at which to start building modules.

  • root_module (Module) (defaults to: Object)

    Module to load the modules into (default Object). You'll probably always want to keep the default.



17
18
19
20
# File 'lib/awesome_loader/module_builder.rb', line 17

def initialize(root_depth:, root_module: Object)
  @root_depth = root_depth
  @root_module = root_module
end

Instance Attribute Details

#root_depthInteger (readonly)

Returns the dir depth at which to start building modules.

Returns:

  • (Integer)

    the dir depth at which to start building modules.



7
8
9
# File 'lib/awesome_loader/module_builder.rb', line 7

def root_depth
  @root_depth
end

#root_moduleModule (readonly)

Returns the root ruby Module.

Returns:

  • (Module)

    the root ruby Module



9
10
11
# File 'lib/awesome_loader/module_builder.rb', line 9

def root_module
  @root_module
end

Instance Method Details

#module(rel_path) ⇒ Module

Returns (recursively creating if necessary) the Module represented by the dir path. The path should be relative to your application root/working directory. Directories are expected to use snake case, and the Modules will use camel case.

# Since root_depth is 2, the first 2 dirs in any path will be ignored
builder = ModuleBuilder.new(root_depth: 2)

builder.module('src/models')
=> Object

builder.module('src/features/billing')
=> Billing

builder.module('src/services/billing/foo')
=> Billing::Foo

Parameters:

  • rel_filepath (String)

    The path, relative to your application root, to the file you want the module for.

Returns:

  • (Module)

    The module



42
43
44
45
46
47
48
49
50
# File 'lib/awesome_loader/module_builder.rb', line 42

def module(rel_path)
  module_names(rel_path).reduce(root_module) { |parent_mod, mod_name|
    if parent_mod.const_defined? mod_name, false
      parent_mod.const_get mod_name 
    else
      parent_mod.const_set mod_name, Module.new
    end
  }
end

#module_names(rel_path) ⇒ Array<String>

Returns an array of nested Module names based on the directory structure of the given path.

builder = ModuleBuilder.new(root_depth: 2)

# Since root_depth is 2, 'src' and 'models' are ignored and there aren't any modules
builder.nested_dirs('src/models')
=> []

builder.nested_dirs('src/features/billing')
=> ['Billing']

builder.nested_dirs('src/features/billing/foo')
=> ['Billing', 'Foo']

Parameters:

  • rel_filepath (String)

    The path, relative to your application root, to the file you want the module for.

Returns:

  • (Array<String>)

    Array of nested Module names



70
71
72
73
74
# File 'lib/awesome_loader/module_builder.rb', line 70

def module_names(rel_path)
  dir_names = Utils.clean_path(rel_path).split '/'
  return [] if rel_path == '.' or root_depth > dir_names.size
  dir_names[root_depth..-1].map { |name| Utils.camelize name }
end