Sha256: d41f2cb39c61d7f2e70acb8580037bce8800eed69c80e38635ee3faf52d77240

Contents?: true

Size: 1.5 KB

Versions: 1

Compression:

Stored size: 1.5 KB

Contents

# frozen_string_literal: true

require "concurrent/array"

module Dry
  module Core
    # An implementation of descendants tracker, heavily inspired
    # by the descendants_tracker gem.
    #
    # @example
    #
    #   class Base
    #     extend Dry::Core::DescendantsTracker
    #   end
    #
    #   class A < Base
    #   end
    #
    #   class B < Base
    #   end
    #
    #   class C < A
    #   end
    #
    #   Base.descendants # => [C, B, A]
    #   A.descendants # => [C]
    #   B.descendants # => []
    #
    module DescendantsTracker
      class << self
        # @api private
        def setup(target)
          target.instance_variable_set(:@descendants, ::Concurrent::Array.new)
        end

        private

        # @api private
        def extended(base)
          super

          DescendantsTracker.setup(base)
        end
      end

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

      protected

      # @api private
      def add_descendant(descendant)
        ancestor = superclass
        if ancestor.respond_to?(:add_descendant, true)
          ancestor.add_descendant(descendant)
        end
        descendants.unshift(descendant)
      end

      private

      # @api private
      def inherited(descendant)
        super

        DescendantsTracker.setup(descendant)
        add_descendant(descendant)
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
dry-core-1.1.0 lib/dry/core/descendants_tracker.rb