module Puppet::Util::ClassGen

This is a utility module for generating classes. @api public

Attributes

name[R]

Public Instance Methods

genclass(name, options = {}, &block) click to toggle source

Create a new class. @param name [String] the name of the generated class @param options [Hash] a hash of options @option options [Array<Class>] :array if specified, the generated class is appended to this array @option options [Hash<{String => Object}>] :attributes a hash that is applied to the generated class

by calling setter methods corresponding to this hash's keys/value pairs. This is done before the given
block is evaluated.

@option options [Proc] :block a block to evaluate in the context of the class (this block can be provided

this way, or as a normal yield block).

@option options [String] :constant (name with first letter capitalized) what to set the constant that references

the generated class to.

@option options [Hash] :hash a hash of existing classes that this class is appended to (name => class).

This hash must be specified if the `:overwrite` option is set to `true`.

@option options [Boolean] :overwrite whether an overwrite of an existing class should be allowed (requires also

defining the `:hash` with existing classes as the test is based on the content of this hash).

@option options [Class] :parent (self) the parent class of the generated class. @option options [String] ('') :prefix the constant prefix to prepend to the constant name referencing the

generated class.

@return [Class] the generated class

   # File lib/puppet/util/classgen.rb
33 def genclass(name, options = {}, &block)
34   genthing(name, Class, options, block)
35 end
genmodule(name, options = {}, &block) click to toggle source

Creates a new module. @param name [String] the name of the generated module @param options [Hash] hash with options @option options [Array<Class>] :array if specified, the generated class is appended to this array @option options [Hash<{String => Object}>] :attributes a hash that is applied to the generated class

by calling setter methods corresponding to this hash's keys/value pairs. This is done before the given
block is evaluated.

@option options [Proc] :block a block to evaluate in the context of the class (this block can be provided

this way, or as a normal yield block).

@option options [String] :constant (name with first letter capitalized) what to set the constant that references

the generated class to.

@option options [Hash] :hash a hash of existing classes that this class is appended to (name => class).

This hash must be specified if the `:overwrite` option is set to `true`.

@option options [Boolean] :overwrite whether an overwrite of an existing class should be allowed (requires also

defining the `:hash` with existing classes as the test is based on the content of this hash).
the capitalized name is appended and the result is set as the constant.

@option options [String] ('') :prefix the constant prefix to prepend to the constant name referencing the

generated class.

@return [Module] the generated Module

   # File lib/puppet/util/classgen.rb
56 def genmodule(name, options = {}, &block)
57   genthing(name, Module, options, block)
58 end
rmclass(name, options) click to toggle source

Removes an existing class. @param name [String] the name of the class to remove @param options [Hash] options @option options [Hash] :hash a hash of existing classes from which the class to be removed is also removed @return [Boolean] whether the class was removed or not

   # File lib/puppet/util/classgen.rb
66 def rmclass(name, options)
67   const = genconst_string(name, options)
68   retval = false
69   if is_constant_defined?(const)
70     remove_const(const)
71     retval = true
72   end
73 
74   hash = options[:hash]
75   if hash && hash.include?(name)
76     hash.delete(name)
77     retval = true
78   end
79 
80   # Let them know whether we did actually delete a subclass.
81   retval
82 end

Private Instance Methods

genconst_string(name, options) click to toggle source

Generates the constant to create or remove. @api private

   # File lib/puppet/util/classgen.rb
88 def genconst_string(name, options)
89   const = options[:constant]
90   unless const
91     prefix = options[:prefix] || ""
92     const = prefix + name2const(name)
93   end
94 
95   const
96 end
genthing(name, type, options, block) click to toggle source

This does the actual work of creating our class or module. It's just a slightly abstract version of genclass. @api private

    # File lib/puppet/util/classgen.rb
101 def genthing(name, type, options, block)
102   name = name.to_s.downcase.intern
103 
104   if type == Module
105     #evalmethod = :module_eval
106     evalmethod = :class_eval
107     # Create the class, with the correct name.
108     klass = Module.new do
109       class << self
110         attr_reader :name
111       end
112       @name = name
113     end
114   else
115     options[:parent] ||= self
116     evalmethod = :class_eval
117     # Create the class, with the correct name.
118     klass = Class.new(options[:parent]) do
119       @name = name
120     end
121   end
122 
123   # Create the constant as appropriation.
124   handleclassconst(klass, name, options)
125 
126   # Initialize any necessary variables.
127   initclass(klass, options)
128 
129   block ||= options[:block]
130 
131   # Evaluate the passed block if there is one.  This should usually
132   # define all of the work.
133   klass.send(evalmethod, &block) if block
134 
135   klass.postinit if klass.respond_to? :postinit
136 
137   # Store the class in hashes or arrays or whatever.
138   storeclass(klass, name, options)
139 
140   klass
141 end
handleclassconst(klass, name, options) click to toggle source

Handle the setting and/or removing of the associated constant. @api private

    # File lib/puppet/util/classgen.rb
152 def handleclassconst(klass, name, options)
153  const = genconst_string(name, options)
154 
155   if is_constant_defined?(const)
156     if options[:overwrite]
157       Puppet.info _("Redefining %{name} in %{klass}") % { name: name, klass: self }
158       remove_const(const)
159     else
160       raise Puppet::ConstantAlreadyDefined,
161         _("Class %{const} is already defined in %{klass}") % { const: const, klass: self }
162     end
163   end
164   const_set(const, klass)
165 
166   const
167 end
initclass(klass, options) click to toggle source

Perform the initializations on the class. @api private

    # File lib/puppet/util/classgen.rb
172 def initclass(klass, options)
173   klass.initvars if klass.respond_to? :initvars
174 
175   attrs = options[:attributes]
176   if attrs
177     attrs.each do |param, value|
178       method = param.to_s + "="
179       klass.send(method, value) if klass.respond_to? method
180     end
181   end
182 
183   [:include, :extend].each do |method|
184     set = options[method]
185     if set
186       set = [set] unless set.is_a?(Array)
187       set.each do |mod|
188         klass.send(method, mod)
189       end
190     end
191   end
192 
193   klass.preinit if klass.respond_to? :preinit
194 end
is_constant_defined?(const) click to toggle source

@api private

    # File lib/puppet/util/classgen.rb
145 def is_constant_defined?(const)
146   const_defined?(const, false)
147 end
name2const(name) click to toggle source

Convert our name to a constant. @api private

    # File lib/puppet/util/classgen.rb
198 def name2const(name)
199   name.to_s.capitalize
200 end
storeclass(klass, klassname, options) click to toggle source

Store the class in the appropriate places. @api private

    # File lib/puppet/util/classgen.rb
204 def storeclass(klass, klassname, options)
205   hash = options[:hash]
206   if hash
207     if hash.include? klassname and ! options[:overwrite]
208       raise Puppet::SubclassAlreadyDefined,
209         _("Already a generated class named %{klassname}") % { klassname: klassname }
210     end
211 
212     hash[klassname] = klass
213   end
214 
215   # If we were told to stick it in a hash, then do so
216   array = options[:array]
217   if array
218     if (klass.respond_to? :name and
219             array.find { |c| c.name == klassname } and
220             ! options[:overwrite])
221       raise Puppet::SubclassAlreadyDefined,
222         _("Already a generated class named %{klassname}") % { klassname: klassname }
223     end
224 
225     array << klass
226   end
227 end