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
32 def genclass(name, options = {}, &block)
33   genthing(name, Class, options, block)
34 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
55 def genmodule(name, options = {}, &block)
56   genthing(name, Module, options, block)
57 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
65 def rmclass(name, options)
66   const = genconst_string(name, options)
67   retval = false
68   if is_constant_defined?(const)
69     remove_const(const)
70     retval = true
71   end
72 
73   hash = options[:hash]
74   if hash && hash.include?(name)
75     hash.delete(name)
76     retval = true
77   end
78 
79   # Let them know whether we did actually delete a subclass.
80   retval
81 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
87 def genconst_string(name, options)
88   const = options[:constant]
89   unless const
90     prefix = options[:prefix] || ""
91     const = prefix + name2const(name)
92   end
93 
94   const
95 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
100 def genthing(name, type, options, block)
101   name = name.to_s.downcase.intern
102 
103   if type == Module
104     #evalmethod = :module_eval
105     evalmethod = :class_eval
106     # Create the class, with the correct name.
107     klass = Module.new do
108       class << self
109         attr_reader :name
110       end
111       @name = name
112     end
113   else
114     options[:parent] ||= self
115     evalmethod = :class_eval
116     # Create the class, with the correct name.
117     klass = Class.new(options[:parent]) do
118       @name = name
119     end
120   end
121 
122   # Create the constant as appropriation.
123   handleclassconst(klass, name, options)
124 
125   # Initialize any necessary variables.
126   initclass(klass, options)
127 
128   block ||= options[:block]
129 
130   # Evaluate the passed block if there is one.  This should usually
131   # define all of the work.
132   klass.send(evalmethod, &block) if block
133 
134   klass.postinit if klass.respond_to? :postinit
135 
136   # Store the class in hashes or arrays or whatever.
137   storeclass(klass, name, options)
138 
139   klass
140 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
151 def handleclassconst(klass, name, options)
152  const = genconst_string(name, options)
153 
154   if is_constant_defined?(const)
155     if options[:overwrite]
156       Puppet.info _("Redefining %{name} in %{klass}") % { name: name, klass: self }
157       remove_const(const)
158     else
159       raise Puppet::ConstantAlreadyDefined,
160         _("Class %{const} is already defined in %{klass}") % { const: const, klass: self }
161     end
162   end
163   const_set(const, klass)
164 
165   const
166 end
initclass(klass, options) click to toggle source

Perform the initializations on the class. @api private

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

@api private

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

Convert our name to a constant. @api private

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

Store the class in the appropriate places. @api private

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