File: descendants_tracker.rb

package info (click to toggle)
ruby-descendants-tracker 0.0.4-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 216 kB
  • sloc: ruby: 86; makefile: 2
file content (65 lines) | stat: -rw-r--r-- 1,274 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# encoding: utf-8

require 'thread_safe'

# Module that adds descendant tracking to a class
module DescendantsTracker

  # Return the descendants of this class
  #
  # @example
  #   descendants = ParentClass.descendants
  #
  # @return [Array<Class<DescendantsTracker>>]
  #
  # @api public
  attr_reader :descendants

  # Setup the class for descendant tracking
  #
  # @param [Class<DescendantsTracker>] descendant
  #
  # @return [undefined]
  #
  # @api private
  def self.setup(descendant)
    descendant.instance_variable_set(:@descendants, ThreadSafe::Array.new)
  end

  class << self
    alias_method :extended, :setup
    private :extended
  end

  # Add the descendant to this class and the superclass
  #
  # @param [Class] descendant
  #
  # @return [self]
  #
  # @api private
  def add_descendant(descendant)
    ancestor = superclass
    if ancestor.respond_to?(:add_descendant)
      ancestor.add_descendant(descendant)
    end
    descendants.unshift(descendant)
    self
  end

private

  # Hook called when class is inherited
  #
  # @param [Class] descendant
  #
  # @return [self]
  #
  # @api private
  def inherited(descendant)
    super
    DescendantsTracker.setup(descendant)
    add_descendant(descendant)
  end

end # module DescendantsTracker