module Eco::API::Common::ClassAutoLoader
Helpers for dynamic object loading based on class declaration @note
- this helpers aim to boost the usage of the ruby language in complex api configurations.
Public Instance Methods
# File lib/eco/api/common/class_auto_loader.rb, line 38 def _autoload_namespace(type, *namespaces) autoloaded_namespaces(type).concat(namespaces) unless namespaces.empty? end
It loads/creates a new instance of children classes pending to be loaded. @return [Boolean] `true` if there were children loaded, `false` otherwise.
# File lib/eco/api/common/class_auto_loader.rb, line 77 def autoload_children(object) 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 = klass.new(object) autoloaded_children.push(klass) end @loading_children = false true end
@param constant [Class, String] a class or namespace we want to check auto-load entitlement thereof. @return [Boolean] determines if a given namespace is entitled for autoloading
# File lib/eco/api/common/class_auto_loader.rb, line 44 def autoload_class?(constant) constants = "#{constant}".split("::").compact autoload = true unless autoloaded_namespaces(:include).empty? autoload = autoloaded_namespaces(:include).any? do |ns| "#{ns}".split("::").compact.zip(constants).all? {|(r, c)| r == c} end end unless autoloaded_namespaces(:ignore).empty? autoload &&= autoloaded_namespaces(:ignore).none? do |ns| "#{ns}".split("::").compact.zip(constants).all? {|(r, c)| r == c} end end autoload end
To restrict which namespaces it is allowed to load from
# File lib/eco/api/common/class_auto_loader.rb, line 29 def autoload_namespace(*namespaces) _autoload_namespace(:include, *namespaces) end
To ignore certain namespaces this class should not autoload from
# File lib/eco/api/common/class_auto_loader.rb, line 34 def autoload_namespace_ignore(*namespaces) _autoload_namespace(:ignore, *namespaces) end
As children are loaded as they are declared, we should not load twice same children.
# File lib/eco/api/common/class_auto_loader.rb, line 61 def autoloaded_children @auto_loaded_children ||= [] end
Resolves the class `autoloader_class` if it has been defined via `autoloads_children_of`
# File lib/eco/api/common/class_auto_loader.rb, line 17 def autoloaded_class return nil unless @autoloaded_class autoloader_class end
To which restricted namespaces this class autoloads from
# File lib/eco/api/common/class_auto_loader.rb, line 23 def autoloaded_namespaces(type = :include) @autoloaded_namespaces ||= {} @autoloaded_namespaces[type] ||= [] end
To enable the class autoloader, you should use this method
# File lib/eco/api/common/class_auto_loader.rb, line 11 def autoloads_children_of(klass) class_resolver :autoloader_class, klass @autoloaded_class = klass end
Add to known namespaces
# File lib/eco/api/common/class_auto_loader.rb, line 97 def known_class!(*classes) known_classes.concat(classes) end
Known namespaces serves the purpose to discover recently added namespaces
provided that the namespace discovery is optimized
# File lib/eco/api/common/class_auto_loader.rb, line 92 def known_classes @known_classes ||= [] end
List all new namespaces
# File lib/eco/api/common/class_auto_loader.rb, line 102 def new_classes ObjectSpace.each_object(::Class).to_a - known_classes end
Children classes of `autoloader_class` that have not been created an instance of.
# File lib/eco/api/common/class_auto_loader.rb, line 66 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