Class: DeepCover::AutoloadTracker
- Inherits:
-
Object
- Object
- DeepCover::AutoloadTracker
- Defined in:
- lib/deep_cover/autoload_tracker.rb
Class Method Summary collapse
-
.value_from_weak_ref(weak_ref) ⇒ Object
A simple if the ref is dead, return nil.
Instance Method Summary collapse
- #add(const, name, path) ⇒ Object
-
#autoloaded_paths_matching_absolute(absolute_path) ⇒ Object
We need all the paths of autoloaded_path that match a given absolute_path Since this can happen a lot, a cache is made which only chan.
-
#initialize(autoloaded_paths = {}) ⇒ AutoloadTracker
constructor
A new instance of AutoloadTracker.
- #initialize_autoloaded_paths ⇒ Object
- #pairs_for_absolute_path(absolute_path) ⇒ Object
- #wrap_require(absolute_path) ⇒ Object
Constructor Details
#initialize(autoloaded_paths = {}) ⇒ AutoloadTracker
Returns a new instance of AutoloadTracker.
7 8 9 |
# File 'lib/deep_cover/autoload_tracker.rb', line 7 def initialize(autoloaded_paths = {}) @autoloaded_paths = autoloaded_paths end |
Class Method Details
.value_from_weak_ref(weak_ref) ⇒ Object
A simple if the ref is dead, return nil. WTF ruby, why is there no such simple interface ?!
74 75 76 |
# File 'lib/deep_cover/autoload_tracker.rb', line 74 def self.value_from_weak_ref(weak_ref) WeakRef.class_variable_get(:@@__map)[weak_ref] end |
Instance Method Details
#add(const, name, path) ⇒ Object
11 12 13 14 15 16 17 18 19 |
# File 'lib/deep_cover/autoload_tracker.rb', line 11 def add(const, name, path) ext = File.extname(path) # We don't care about .so files return if ext == '.so' path += '.rb' if ext != '.rb' pairs = @autoloaded_paths[path] ||= [] pairs << [WeakRef.new(const), name] end |
#autoloaded_paths_matching_absolute(absolute_path) ⇒ Object
We need all the paths of autoloaded_path that match a given absolute_path Since this can happen a lot, a cache is made which only chan
66 67 68 69 70 |
# File 'lib/deep_cover/autoload_tracker.rb', line 66 def autoloaded_paths_matching_absolute(absolute_path) @autoloaded_paths.keys.select do |path| absolute_path == DeepCover.custom_requirer.resolve_path(path) end end |
#initialize_autoloaded_paths ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/deep_cover/autoload_tracker.rb', line 52 def initialize_autoloaded_paths @autoloaded_paths = {} # This is only used on MRI, so ObjectSpace is alright. ObjectSpace.each_object(Module) do |mod| mod.constants.each do |name| if (path = mod.autoload?(name)) add(mod, name, path) end end end end |
#pairs_for_absolute_path(absolute_path) ⇒ Object
21 22 23 24 25 26 27 28 29 30 |
# File 'lib/deep_cover/autoload_tracker.rb', line 21 def pairs_for_absolute_path(absolute_path) paths = autoloaded_paths_matching_absolute(absolute_path) paths.flat_map do |path| pairs = @autoloaded_paths[path] || [] pairs = pairs.map { |weak_const, name| [self.class.value_from_weak_ref(weak_const), name] } pairs.select!(&:first) pairs end end |
#wrap_require(absolute_path) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/deep_cover/autoload_tracker.rb', line 32 def wrap_require(absolute_path) pairs = pairs_for_absolute_path(absolute_path) begin pairs.each do |const, name| # Changing the autoload to an already loaded file (this one) const.autoload_without_deep_cover(name, __FILE__) end yield rescue Exception pairs.each do |const, name| # Changing the autoload to an already loaded file (this one) const.autoload_without_deep_cover(name, absolute_path) end raise end end |