Module: RakeCommander::Base::ClassAutoLoader
- Includes:
- ClassHelpers
- Defined in:
- lib/rake-commander/base/class_auto_loader.rb
Overview
- 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
-
#_autoload_namespace(type, *namespaces) ⇒ Object
Applies a change to the
autoloaded_namespaces
. -
#autoload_children(object = nil) ⇒ Boolean
It loads/creates a new instance of children classes pending to be loaded.
-
#autoload_class?(constant) ⇒ Boolean
Determines if a given namespace is entitled for autoloading.
-
#autoload_namespace(*namespaces) ⇒ Object
To restrict which namespaces it is allowed to load from.
-
#autoload_namespace_ignore(*namespaces) ⇒ Object
To ignore certain namespaces this class should not autoload from.
-
#autoloaded_children ⇒ Object
As children are loaded as they are declared, we should not load twice same children.
-
#autoloaded_class ⇒ Object
Resolves the class
autoloader_class
if it has been defined viaautoloads_children_of
. -
#autoloaded_namespaces(type = :include) ⇒ Object
To which restricted namespaces this class autoloads from.
-
#autoloads_children_of(klass) ⇒ Object
To enable the class autoloader, you should use this method.
-
#clear_autoloaded_children ⇒ Object
Allows to reload.
-
#excluded_children ⇒ Object
Prevents already excluded children to enter into the loop again.
-
#forget_class!(*classes) ⇒ Object
Forget namespaces.
-
#ignored_children ⇒ Object
Keep track on actual children that have been ignored by
autoload_namespace_ignore
. -
#known_class!(*classes) ⇒ Object
Add to known namespaces.
-
#known_classes ⇒ Object
Known namespaces serves the purpose to discover recently added namespaces provided that the namespace discovery is optimized.
-
#new_classes ⇒ Object
List all new namespaces.
-
#unloaded_children ⇒ Object
Children classes of
autoloader_class
that have not been created an instance of.
Methods included from ClassHelpers
#class_resolver, #descendants, #descendants?, #new_class, #redef_without_warning, #resolve_class, #sort_classes, #to_constant, #used_param?
Instance Method Details
#_autoload_namespace(type, *namespaces) ⇒ Object
Applies a change to the autoloaded_namespaces
40 41 42 43 44 45 46 47 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 40 def _autoload_namespace(type, *namespaces) autoloaded_namespaces(type).tap do |target| next if namespaces.empty? other_type = type == :include ? :ignore : :include namespaces.each {|nm_sp| autoloaded_namespaces(other_type).delete(nm_sp)} target.concat(namespaces) end end |
#autoload_children(object = nil) ⇒ Boolean
It loads/creates a new instance of children classes pending to be loaded.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 106 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| exclude = false 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) exclude = true excluded_children.push(klass) ensure autoloaded_children.push(klass) unless exclude end @loading_children = false true end |
#autoload_class?(constant) ⇒ Boolean
Returns determines if a given namespace is entitled for autoloading.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 51 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
this deletes from the :ignore
namespaces
To restrict which namespaces it is allowed to load from
29 30 31 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 29 def autoload_namespace(*namespaces) _autoload_namespace(:include, *namespaces) end |
#autoload_namespace_ignore(*namespaces) ⇒ Object
this deletes from the :include
namespaces
To ignore certain namespaces this class should not autoload from
35 36 37 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 35 def autoload_namespace_ignore(*namespaces) _autoload_namespace(:ignore, *namespaces) end |
#autoloaded_children ⇒ Object
As children are loaded as they are declared, we should not load twice same children.
68 69 70 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 68 def autoloaded_children @autoloaded_children ||= [] end |
#autoloaded_class ⇒ Object
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 |
#clear_autoloaded_children ⇒ Object
it may be handy some times.
Allows to reload
79 80 81 82 83 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 79 def clear_autoloaded_children forget_class!(*autoloaded_children, *ignored_children) @ignored_children = [] @autoloaded_children = [] end |
#excluded_children ⇒ Object
Prevents already excluded children to enter into the loop again.
86 87 88 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 86 def excluded_children @excluded_children ||= [] end |
#forget_class!(*classes) ⇒ Object
Forget namespaces
139 140 141 142 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 139 def forget_class!(*classes) @known_classes = known_classes - classes self end |
#ignored_children ⇒ Object
Keep track on actual children that have been ignored by autoload_namespace_ignore
.
73 74 75 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 73 def ignored_children @ignored_children ||= [] end |
#known_class!(*classes) ⇒ Object
Add to known namespaces
133 134 135 136 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 133 def known_class!(*classes) known_classes.concat(classes) self end |
#known_classes ⇒ Object
Known namespaces serves the purpose to discover recently added namespaces provided that the namespace discovery is optimized
128 129 130 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 128 def known_classes @known_classes ||= [] end |
#new_classes ⇒ Object
List all new namespaces
145 146 147 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 145 def new_classes ObjectSpace.each_object(::Class).to_a - known_classes end |
#unloaded_children ⇒ Object
Children classes of autoloader_class
that have not been created an instance of.
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/rake-commander/base/class_auto_loader.rb', line 91 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) && \ !excluded_children.include?(child_class) && \ autoload_class?(child_class).tap do |ignored| ignored_children.push(child_class) if ignored end end end |