Class: Truck::Autoloader

Inherits:
Object
  • Object
show all
Extended by:
HandleConstMissing, ThreadedState
Defined in:
lib/truck/autoloader.rb

Defined Under Namespace

Modules: HandleConstMissing, NullModule, ThreadedState

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ThreadedState

autoloaders, current_autoloader, current_thread_id, set_current_autoloader

Methods included from HandleConstMissing

handle, handle!

Constructor Details

#initialize(from, file) ⇒ Autoloader

Returns a new instance of Autoloader.



7
8
9
10
11
12
# File 'lib/truck/autoloader.rb', line 7

def initialize(from, file)
  @from = from
  @file = file
  @context, @base_nibbles = fetch_context_and_base_nibbles
  @dir_paths = [nil]
end

Instance Attribute Details

#base_nibblesObject (readonly)

Returns the value of attribute base_nibbles.



5
6
7
# File 'lib/truck/autoloader.rb', line 5

def base_nibbles
  @base_nibbles
end

#contextObject (readonly)

Returns the value of attribute context.



5
6
7
# File 'lib/truck/autoloader.rb', line 5

def context
  @context
end

#dir_pathsObject (readonly)

Returns the value of attribute dir_paths.



5
6
7
# File 'lib/truck/autoloader.rb', line 5

def dir_paths
  @dir_paths
end

#fileObject (readonly)

Returns the value of attribute file.



5
6
7
# File 'lib/truck/autoloader.rb', line 5

def file
  @file
end

#fromObject (readonly)

Returns the value of attribute from.



5
6
7
# File 'lib/truck/autoloader.rb', line 5

def from
  @from
end

Instance Method Details

#<<(const_name) ⇒ Object



14
15
16
17
18
19
20
21
22
23
# File 'lib/truck/autoloader.rb', line 14

def <<(const_name)
  raise_name_error!(const_name) unless context
  @dir_paths = each_possible_const(const_name).reduce [] do |new_paths, possible_const|
    resolved_const = context.resolve_const possible_const, skip: file
    throw :const, resolved_const if resolved_const
    new_paths << possible_const if possible_namespace?(possible_const)
    new_paths
  end
  raise_name_error!(const_name) if dir_paths.empty?
end

#constify(*nibbles) ⇒ Object



37
38
39
# File 'lib/truck/autoloader.rb', line 37

def constify(*nibbles)
  nibbles.compact.join '::'
end

#each_base_nibbleObject

given “Foo::Bar::Baz”, return [“Foo”, “Bar”, “Baz”]



59
60
61
62
63
64
65
66
# File 'lib/truck/autoloader.rb', line 59

def each_base_nibble
  return to_enum(:each_base_nibble) unless block_given?
  from.name.split('::').reduce Object do |mod, const|
    mod = mod.const_get const
    yield [mod, const]
    mod
  end
end

#each_possible_const(const_name) ⇒ Object



25
26
27
28
29
30
31
# File 'lib/truck/autoloader.rb', line 25

def each_possible_const(const_name)
  return to_enum(:each_possible_const, const_name) unless block_given?
  dir_paths.each do |dir_path|
    base_nibbles.map { |e| yield constify(e, *dir_path, const_name) }
    yield constify(*dir_path, const_name)
  end
end

#fetch_context_and_base_nibblesObject

given “Foo::Bar::Baz”, return [“Foo::Bar::Baz”, “Foo::Bar”, etc.]



48
49
50
51
52
53
54
55
56
# File 'lib/truck/autoloader.rb', line 48

def fetch_context_and_base_nibbles
  each_base_nibble.to_a.reverse.reduce [] do |ary, (mod, const)|
    owner = Truck.contexts.each_value.detect { |c| c.context_for? mod }
    return [owner, ary] if owner
    ary.map! do |e| e.insert 0, '::'; e.insert 0, const; end
    ary << const
  end
  nil
end

#possible_namespace?(possible_const) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
# File 'lib/truck/autoloader.rb', line 33

def possible_namespace?(possible_const)
  context.root.join(possible_const.to_snake_case).directory?
end

#raise_name_error!(const_name = dir_paths.last) ⇒ Object

Raises:

  • (NameError)


41
42
43
44
45
# File 'lib/truck/autoloader.rb', line 41

def raise_name_error!(const_name = dir_paths.last)
  message = "uninitialized constant #{const_name}"
  message << " (in #{context.mod})" if context
  raise NameError, message
end