Module: Aws::Templates::Utils::Autoload
- Included in:
- Module
- Defined in:
- lib/aws/templates/utils/autoload.rb
Overview
Lazy load implementation
It allows to skip ‘require’ definitions and load all classes and modules by convention.
Constant Summary collapse
- REQUIRE_LOCKER =
Concurrent::Map.new
- MODULE_LOCKER =
Concurrent::Map.new
- Trace =
TracePoint.new(:class) { |tp| Autoload.autoload!(tp.self) }
Class Method Summary collapse
- ._check_if_required(path, obj) ⇒ Object
- ._try_to_require(path, mutex) ⇒ Object
- .atomic_require(path) ⇒ Object
- .autoload!(mod) ⇒ Object
- .const_is_loaded?(mod, const_name) ⇒ Boolean
- .const_path_for(mod, const_name) ⇒ Object
- .sanitize_load_exception(e, path) ⇒ Object
Instance Method Summary collapse
- #const_missing(const_name) ⇒ Object
- #lazy ⇒ Object
- #reduce(_ = false) ⇒ Object
- #root_namespace? ⇒ Boolean
Class Method Details
._check_if_required(path, obj) ⇒ Object
28 29 30 31 32 33 34 35 |
# File 'lib/aws/templates/utils/autoload.rb', line 28 def self._check_if_required(path, obj) raise(obj) if obj.is_a?(::Exception) return if obj.owned? obj.lock.unlock locker_obj = REQUIRE_LOCKER[path] raise locker_obj if locker_obj.is_a?(Exception) end |
._try_to_require(path, mutex) ⇒ Object
19 20 21 22 23 24 25 26 |
# File 'lib/aws/templates/utils/autoload.rb', line 19 def self._try_to_require(path, mutex) require path rescue ScriptError, NoMemoryError, StandardError => e REQUIRE_LOCKER.get_and_set(path, e) raise e ensure mutex.unlock end |
.atomic_require(path) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/aws/templates/utils/autoload.rb', line 37 def self.atomic_require(path) mutex = Mutex.new.lock obj = REQUIRE_LOCKER.put_if_absent(path, mutex) if obj.nil? _try_to_require(path, mutex) else _check_if_required(path, obj) end true end |
.autoload!(mod) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/aws/templates/utils/autoload.rb', line 51 def self.autoload!(mod) return if mod.name.nil? MODULE_LOCKER.compute_if_absent(mod) do path = mod.pathize begin atomic_require path rescue LoadError => e sanitize_load_exception(e, path) end true end end |
.const_is_loaded?(mod, const_name) ⇒ Boolean
81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/aws/templates/utils/autoload.rb', line 81 def self.const_is_loaded?(mod, const_name) const_path = Autoload.const_path_for(mod, const_name) begin atomic_require const_path true rescue LoadError => e Autoload.sanitize_load_exception(e, const_path) false end end |
.const_path_for(mod, const_name) ⇒ Object
67 68 69 70 71 72 73 74 75 |
# File 'lib/aws/templates/utils/autoload.rb', line 67 def self.const_path_for(mod, const_name) raise ScriptError.new("Autoload is not supported for #{mod}") if mod.name.nil? path = const_name.to_s.pathize path = "#{mod.pathize}/#{path}" unless mod.root_namespace? path end |
.sanitize_load_exception(e, path) ⇒ Object
77 78 79 |
# File 'lib/aws/templates/utils/autoload.rb', line 77 def self.sanitize_load_exception(e, path) raise e unless e.path == path end |
Instance Method Details
#const_missing(const_name) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/aws/templates/utils/autoload.rb', line 93 def const_missing(const_name) super(const_name) unless Autoload.const_is_loaded?(self, const_name) unless const_defined?(const_name) raise NameError.new( "::#{self}::#{const_name} is loaded but the constant is missing" ) end const_get(const_name) end |
#lazy ⇒ Object
105 106 107 |
# File 'lib/aws/templates/utils/autoload.rb', line 105 def lazy Lazy.new(self) end |
#reduce(_ = false) ⇒ Object
109 110 111 |
# File 'lib/aws/templates/utils/autoload.rb', line 109 def reduce(_ = false) self end |
#root_namespace? ⇒ Boolean
113 114 115 |
# File 'lib/aws/templates/utils/autoload.rb', line 113 def root_namespace? (self == ::Kernel) || (self == ::Object) end |