Module: Puppet::Util::SubclassLoader
- Included in:
- Network::Handler
- Defined in:
- lib/vendor/puppet/util/subclass_loader.rb
Overview
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.
Instance Attribute Summary collapse
-
#classloader ⇒ Object
Returns the value of attribute classloader.
-
#loader ⇒ Object
Returns the value of attribute loader.
Instance Method Summary collapse
-
#each ⇒ Object
Iterate over each of the subclasses.
-
#handle_subclasses(name, path) ⇒ Object
The hook method that sets up subclass loading.
-
#inherited(sub) ⇒ Object
Add a new class to our list.
-
#method_missing(method, *args) ⇒ Object
See if we can load a class.
-
#name(dummy_argument = :work_arround_for_ruby_GC_bug) ⇒ Object
Retrieve or calculate a name.
-
#subclasses ⇒ Object
Provide a list of all subclasses.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
See if we can load a class.
61 62 63 64 65 66 67 |
# File 'lib/vendor/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 |
Instance Attribute Details
#classloader ⇒ Object
Returns the value of attribute classloader.
7 8 9 |
# File 'lib/vendor/puppet/util/subclass_loader.rb', line 7 def classloader @classloader end |
#loader ⇒ Object
Returns the value of attribute loader.
7 8 9 |
# File 'lib/vendor/puppet/util/subclass_loader.rb', line 7 def loader @loader end |
Instance Method Details
#each ⇒ Object
Iterate over each of the subclasses.
10 11 12 13 |
# File 'lib/vendor/puppet/util/subclass_loader.rb', line 10 def each @subclasses ||= [] @subclasses.each { |c| yield c } end |
#handle_subclasses(name, path) ⇒ Object
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.
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 |
# File 'lib/vendor/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. (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) ⇒ Object
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.
50 51 52 53 54 55 56 57 58 |
# File 'lib/vendor/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 |
#name(dummy_argument = :work_arround_for_ruby_GC_bug) ⇒ Object
Retrieve or calculate a name.
70 71 72 73 74 |
# File 'lib/vendor/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 ⇒ Object
Provide a list of all subclasses.
77 78 79 80 |
# File 'lib/vendor/puppet/util/subclass_loader.rb', line 77 def subclasses @loader.loadall @subclasses.collect { |klass| klass.name } end |