Module: RakeCommander::Base::ClassAutoLoader

Includes:
ClassHelpers
Defined in:
lib/rake-commander/base/class_auto_loader.rb

Overview

Note:
  • this helpers aim to boost the usage of the ruby language in complex api configurations.

Helpers for dynamic object loading based on class declaration

Constant Summary

Constants included from ClassHelpers

RakeCommander::Base::ClassHelpers::NOT_USED

Instance Method Summary collapse

Methods included from ClassHelpers

#class_resolver, #descendants, #descendants?, #inheritable_attrs, #inheritable_class_vars, #inherited, #instance_variable_name, #new_class, #redef_without_warning, #resolve_class, #to_constant, #used_param?

Instance Method Details

#_autoload_namespace(type, *namespaces) ⇒ Object



37
38
39
# File 'lib/rake-commander/base/class_auto_loader.rb', line 37

def _autoload_namespace(type, *namespaces)
  autoloaded_namespaces(type).concat(namespaces) unless namespaces.empty?
end

#autoload_children(object = nil) ⇒ Boolean

It loads/creates a new instance of children classes pending to be loaded.

Returns:

  • (Boolean)

    true if there were children loaded, false otherwise.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rake-commander/base/class_auto_loader.rb', line 76

def autoload_children(object = nil)
  return false if !autoloaded_class || @loading_children
  pending_children = unloaded_children
  return false if pending_children.empty?
  @loading_children = true
  pending_children.each do |klass|
    child = object ? klass.new(object) : klass.new
    yield(child) if block_given?

  rescue TypeError
    # Can't create from this class (must be the singleton class)
    # Just ignore
  ensure
    autoloaded_children.push(klass)
  end
  @loading_children = false
  true
end

#autoload_class?(constant) ⇒ Boolean

Returns determines if a given namespace is entitled for autoloading.

Parameters:

  • constant (Class, String)

    a class or namespace we want to check auto-load entitlement thereof.

Returns:

  • (Boolean)

    determines if a given namespace is entitled for autoloading



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rake-commander/base/class_auto_loader.rb', line 43

def autoload_class?(constant)
  constants = constant.to_s.split("::").compact
  autoload = true
  unless autoloaded_namespaces(:include).empty?
    autoload = autoloaded_namespaces(:include).any? do |ns|
      ns.to_s.split("::").compact.zip(constants).all? {|(r, c)| r == c}
    end
  end
  unless autoloaded_namespaces(:ignore).empty?
    autoload &&= autoloaded_namespaces(:ignore).none? do |ns|
      ns.to_s.split("::").compact.zip(constants).all? {|(r, c)| r == c}
    end
  end
  autoload
end

#autoload_namespace(*namespaces) ⇒ Object

To restrict which namespaces it is allowed to load from



28
29
30
# File 'lib/rake-commander/base/class_auto_loader.rb', line 28

def autoload_namespace(*namespaces)
  _autoload_namespace(:include, *namespaces)
end

#autoload_namespace_ignore(*namespaces) ⇒ Object

To ignore certain namespaces this class should not autoload from



33
34
35
# File 'lib/rake-commander/base/class_auto_loader.rb', line 33

def autoload_namespace_ignore(*namespaces)
  _autoload_namespace(:ignore, *namespaces)
end

#autoloaded_childrenObject

As children are loaded as they are declared, we should not load twice same children.



60
61
62
# File 'lib/rake-commander/base/class_auto_loader.rb', line 60

def autoloaded_children
  @autoloaded_children ||= []
end

#autoloaded_classObject

Resolves the class autoloader_class if it has been defined via autoloads_children_of



16
17
18
19
# File 'lib/rake-commander/base/class_auto_loader.rb', line 16

def autoloaded_class
  return nil unless @autoloaded_class
  autoloader_class
end

#autoloaded_namespaces(type = :include) ⇒ Object

To which restricted namespaces this class autoloads from



22
23
24
25
# File 'lib/rake-commander/base/class_auto_loader.rb', line 22

def autoloaded_namespaces(type = :include)
  @autoloaded_namespaces       ||= {}
  @autoloaded_namespaces[type] ||= []
end

#autoloads_children_of(klass) ⇒ Object

To enable the class autoloader, you should use this method



10
11
12
13
# File 'lib/rake-commander/base/class_auto_loader.rb', line 10

def autoloads_children_of(klass)
  class_resolver :autoloader_class, klass
  @autoloaded_class = klass
end

#known_class!(*classes) ⇒ Object

Add to known namespaces



102
103
104
# File 'lib/rake-commander/base/class_auto_loader.rb', line 102

def known_class!(*classes)
  known_classes.concat(classes)
end

#known_classesObject

Known namespaces serves the purpose to discover recently added namespaces provided that the namespace discovery is optimized



97
98
99
# File 'lib/rake-commander/base/class_auto_loader.rb', line 97

def known_classes
  @known_classes ||= []
end

#new_classesObject

List all new namespaces



107
108
109
# File 'lib/rake-commander/base/class_auto_loader.rb', line 107

def new_classes
  ObjectSpace.each_object(::Class).to_a - known_classes
end

#unloaded_childrenObject

Children classes of autoloader_class that have not been created an instance of.



65
66
67
68
69
70
71
72
# File 'lib/rake-commander/base/class_auto_loader.rb', line 65

def unloaded_children
  return [] unless autoloaded_class
  new_detected = new_classes
  known_class!(*new_detected)
  descendants(parent_class: autoloaded_class, scope: new_detected).select do |child_class|
    !autoloaded_children.include?(child_class) && autoload_class?(child_class)
  end.sort
end