Module: ActiveSupport::DescendantsTracker

Defined in:
lib/active_support/descendants_tracker.rb

Overview

Active Support Descendants Tracker

This module provides an internal implementation to track descendants which is faster than iterating through ObjectSpace.

However Ruby 3.1 provide a fast native Class#subclasses method, so if you know your code won’t be executed on older rubies, including ActiveSupport::DescendantsTracker does not provide any benefit.

Defined Under Namespace

Modules: ReloadedClassesFiltering Classes: DescendantsArray, WeakSet

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.clear(classes) ⇒ Object

:nodoc:



79
80
81
82
83
84
85
86
87
88
# File 'lib/active_support/descendants_tracker.rb', line 79

def clear(classes) # :nodoc:
  raise "DescendantsTracker.clear was disabled because config.enable_reloading is false" if @clear_disabled

  classes.each do |klass|
    @excluded_descendants << klass
    klass.descendants.each do |descendant|
      @excluded_descendants << descendant
    end
  end
end

.descendants(klass) ⇒ Object



104
105
106
# File 'lib/active_support/descendants_tracker.rb', line 104

def descendants(klass)
  klass.descendants
end

.disable_clear!Object

:nodoc:



70
71
72
73
74
75
76
77
# File 'lib/active_support/descendants_tracker.rb', line 70

def disable_clear! # :nodoc:
  unless @clear_disabled
    @clear_disabled = true
    ReloadedClassesFiltering.remove_method(:subclasses)
    ReloadedClassesFiltering.remove_method(:descendants)
    @excluded_descendants = nil
  end
end

.reject!(classes) ⇒ Object

:nodoc:



90
91
92
93
94
95
# File 'lib/active_support/descendants_tracker.rb', line 90

def reject!(classes) # :nodoc:
  if @excluded_descendants
    classes.reject! { |d| @excluded_descendants.include?(d) }
  end
  classes
end

.store_inherited(klass, descendant) ⇒ Object

This is the only method that is not thread safe, but is only ever called during the eager loading phase.



170
171
172
# File 'lib/active_support/descendants_tracker.rb', line 170

def store_inherited(klass, descendant) # :nodoc:
  (@direct_descendants[klass] ||= DescendantsArray.new) << descendant
end

.subclasses(klass) ⇒ Object



100
101
102
# File 'lib/active_support/descendants_tracker.rb', line 100

def subclasses(klass)
  klass.subclasses
end

Instance Method Details

#descendantsObject



109
110
111
112
# File 'lib/active_support/descendants_tracker.rb', line 109

def descendants
  subclasses = DescendantsTracker.reject!(self.subclasses)
  subclasses.concat(subclasses.flat_map(&:descendants))
end

#subclassesObject



175
176
177
# File 'lib/active_support/descendants_tracker.rb', line 175

def subclasses
  DescendantsTracker.subclasses(self)
end