diff options
author | Pablo Ifran <pabloifran@gmail.com> | 2012-10-22 09:42:42 -0200 |
---|---|---|
committer | Pablo Ifran <pabloifran@gmail.com> | 2012-10-22 09:42:42 -0200 |
commit | e041a50f2917f82950f9e5666f966d8992afd45d (patch) | |
tree | 9f4d2e3aa88f28dba9d7a1d24d46977e0642a1eb /activesupport/lib/active_support/descendants_tracker.rb | |
parent | 3e6b2f5d38e0f31db3fb0fcd3bbab92666a0e3e2 (diff) | |
parent | ae27acb342c575ce19d5ad78cb13ba23f826fab1 (diff) | |
download | rails-e041a50f2917f82950f9e5666f966d8992afd45d.tar.gz rails-e041a50f2917f82950f9e5666f966d8992afd45d.tar.bz2 rails-e041a50f2917f82950f9e5666f966d8992afd45d.zip |
Merge branch 'master' of https://github.com/lifo/docrails
Conflicts:
activerecord/lib/active_record/callbacks.rb
Diffstat (limited to 'activesupport/lib/active_support/descendants_tracker.rb')
-rw-r--r-- | activesupport/lib/active_support/descendants_tracker.rb | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/activesupport/lib/active_support/descendants_tracker.rb b/activesupport/lib/active_support/descendants_tracker.rb index e2a8b4d4e3..27861e01d0 100644 --- a/activesupport/lib/active_support/descendants_tracker.rb +++ b/activesupport/lib/active_support/descendants_tracker.rb @@ -2,35 +2,50 @@ module ActiveSupport # This module provides an internal implementation to track descendants # which is faster than iterating through ObjectSpace. module DescendantsTracker - @@direct_descendants = Hash.new { |h, k| h[k] = [] } + @@direct_descendants = {} - def self.direct_descendants(klass) - @@direct_descendants[klass] - end + class << self + def direct_descendants(klass) + @@direct_descendants[klass] || [] + end - def self.descendants(klass) - @@direct_descendants[klass].inject([]) do |descendants, _klass| - descendants << _klass - descendants.concat _klass.descendants + def descendants(klass) + arr = [] + accumulate_descendants(klass, arr) + arr end - end - def self.clear - if defined? ActiveSupport::Dependencies - @@direct_descendants.each do |klass, descendants| - if ActiveSupport::Dependencies.autoloaded?(klass) - @@direct_descendants.delete(klass) - else - descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) } + def clear + if defined? ActiveSupport::Dependencies + @@direct_descendants.each do |klass, descendants| + if ActiveSupport::Dependencies.autoloaded?(klass) + @@direct_descendants.delete(klass) + else + descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) } + end end + else + @@direct_descendants.clear + end + end + + # This is the only method that is not thread safe, but is only ever called + # during the eager loading phase. + def store_inherited(klass, descendant) + (@@direct_descendants[klass] ||= []) << descendant + end + + private + def accumulate_descendants(klass, acc) + if direct_descendants = @@direct_descendants[klass] + acc.concat(direct_descendants) + direct_descendants.each { |direct_descendant| accumulate_descendants(direct_descendant, acc) } end - else - @@direct_descendants.clear end end def inherited(base) - self.direct_descendants << base + DescendantsTracker.store_inherited(self, base) super end |