# module Puppet::Util::SubclassLoader

A module for loading subclasses into an array and retrieving them by name. Also sets up a method for each class so that you can just do Klass.subclass, rather than Klass.subclass(:subclass).

This module is currently used by network handlers and clients.

### Attributes

classloader[RW]
loader[RW]

### Public Instance Methods

each() { |c| ... } click to toggle source

Iterate over each of the subclasses.

    # File lib/puppet/util/subclass_loader.rb, line 10
    def each
      @subclasses ||= []
      @subclasses.each { |c| yield c }
    end

handle_subclasses(name, path) click to toggle source

The hook method that sets up subclass loading. We need the name of the method to create and the path in which to look for them.

    # File lib/puppet/util/subclass_loader.rb, line 17
    def handle_subclasses(name, path)
      raise ArgumentError, "Must be a class to use SubclassLoader" unless self.is_a?(Class)
      @subclasses = []

            @loader = Puppet::Util::Autoload.new(
          self,

        path, :wrap => false
      )

      @subclassname = name

      @classloader = self

      # Now create a method for retrieving these subclasses by name.  Note
      # that we're defining a class method here, not an instance.
      meta_def(name) do |subname|
        subname = subname.to_s.downcase

        unless c = @subclasses.find { |c| c.name.to_s.downcase == subname }
          loader.load(subname)
          c = @subclasses.find { |c| c.name.to_s.downcase == subname }

          # Now make the method that returns this subclass.  This way we
          # normally avoid the method_missing method.
          define_method(subname) { c } if c and ! respond_to?(subname)
        end
        return c
      end
    end

inherited(sub) click to toggle source

Add a new class to our list. Note that this has to handle subclasses of subclasses, thus the reason we’re keeping track of the @@classloader.

    # File lib/puppet/util/subclass_loader.rb, line 50
    def inherited(sub)
      @subclasses ||= []
      sub.classloader = self.classloader
      if self.classloader == self
        @subclasses << sub
      else
        @classloader.inherited(sub)
      end
    end

method_missing(method, *args) click to toggle source

See if we can load a class.

Calls superclass method

    # File lib/puppet/util/subclass_loader.rb, line 61
    def method_missing(method, *args)
      unless self == self.classloader
        super
      end
      return nil unless defined?(@subclassname)
      self.send(@subclassname, method) || nil
    end

name(dummy_argument=:work_arround_for_ruby_GC_bug) click to toggle source

Retrieve or calculate a name.

    # File lib/puppet/util/subclass_loader.rb, line 70
    def name(dummy_argument=:work_arround_for_ruby_GC_bug)
      @name ||= self.to_s.sub(/.+::/, '').intern

      @name
    end

subclasses() click to toggle source

Provide a list of all subclasses.

    # File lib/puppet/util/subclass_loader.rb, line 77
    def subclasses
      @loader.loadall
      @subclasses.collect { |klass| klass.name }
    end