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