Module: CTioga2::Data::Backends::BackendDescriptionExtend

Included in:
Backend
Defined in:
lib/ctioga2/data/backends/description.rb

Overview

This module should be used with extend to provide the class with descriptions functionnalities. Please not that all the instance methods defined here will become class methods in the class you extend.

This module defines several methods to add a description (#describe) to a class, to add parameters (#param, #param_noaccess) and to import parameters from parents (#inherit_parameters).

Factories can be created using the #craete_factory statement. This makes the current class the factory repository for all the subclasses. It creates a factory class method returning the base factory. You can use #register_class to register the current class into the base factory class.

Instance Method Summary collapse

Instance Method Details

#base_descriptionObject

Returns the base description if there is one, or nil if there isn’t



255
256
257
258
259
260
261
# File 'lib/ctioga2/data/backends/description.rb', line 255

def base_description
  if has_factory?
    return factory.description
  else
    return nil
  end
end

#create_factory(auto = true, register_self = false) ⇒ Object

Makes this class the factory class for all subclasses. It creates four class methods: base_factory, that always points to the closest factory in the hierarchy and three methods used internally.

If auto is true, the subclasses are all automatically registered to the factory. If register_self is true the class itself is registered. It is probably not a good idea, so it is off by default.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/ctioga2/data/backends/description.rb', line 220

def create_factory(auto = true, register_self = false)
  cls = self
  # we create a temporary module so that we can use
  # define_method with a block and extend this class with it
  mod = Module.new
  mod.send(:define_method, :factory) do
    return cls
  end
  mod.send(:define_method, :private_description_list) do
    return @registered_descriptions
  end
  mod.send(:define_method, :private_description_hash) do
    return @registered_descriptions_hash
  end
  # Creates an accessor for the factory class
  mod.send(:define_method, :private_auto_register) do 
    @auto_register_subclasses
  end
  self.extend(mod)

  # Creates the necessary arrays|hashes to handle the
  # registered classes:
  @registered_descriptions = []
  @registered_descriptions_hash = {}

  @auto_register_subclasses = auto
end

#describe(name, longname = name, desc = "") ⇒ Object

Creates a description attached to the current class. It needs to be used before anything else.



377
378
379
380
# File 'lib/ctioga2/data/backends/description.rb', line 377

def describe(name, longname = name, desc = "")
  d = Description.new(self, name, longname, desc)
  set_description(d)
end

#descriptionObject

Returns the Description of the class.



300
301
302
# File 'lib/ctioga2/data/backends/description.rb', line 300

def description
  return @description
end

#factory_class(name) ⇒ Object

Returns the Class object associated with the given name in the factory



285
286
287
# File 'lib/ctioga2/data/backends/description.rb', line 285

def factory_class(name)
  return factory_description(name).object_class
end

#factory_description(name) ⇒ Object

Returns the factory description with the given name



278
279
280
281
# File 'lib/ctioga2/data/backends/description.rb', line 278

def factory_description(name)
  raise "Must have a factory" unless has_factory?
  return factory_description_hash.fetch(name)
end

#factory_description_hashObject

Returns the description hash of the factory. Raises an exception if there is no factory



272
273
274
275
# File 'lib/ctioga2/data/backends/description.rb', line 272

def factory_description_hash
  raise "Must have a factory" unless has_factory?
  return factory.private_description_hash
end

#factory_description_listObject

Returns the description list of the factory. Raises an exception if there is no factory



265
266
267
268
# File 'lib/ctioga2/data/backends/description.rb', line 265

def factory_description_list
  raise "Must have a factory" unless has_factory?
  return factory.private_description_list
end

#has_factory?Boolean

Checks if the class has a factory

Returns:

  • (Boolean)


249
250
251
# File 'lib/ctioga2/data/backends/description.rb', line 249

def has_factory?
  return self.respond_to?(:factory)
end

#inherit_parameters(*names) ⇒ Object

Imports the given parameters directly from the parent class. This function is quite naive and will not look further than the direct #superclass.



386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/ctioga2/data/backends/description.rb', line 386

def inherit_parameters(*names)
  if self.superclass.respond_to?(:description)
    parents_params = self.superclass.description.param_hash
    for n in names
      if parents_params.key?(n)
        description.add_param(parents_params[n])
      else
        warn { "Param #{n} not found" }
      end
    end
  else
    warn { "The parent class has no description" }
  end
end

#param(writer, reader, name, long_name, type, desc = "") ⇒ Object

Registers an new parameter, with the following properties:

  • writer is the name of the method used to write that parameter;

  • reader the name of the method that returns its current value;

  • name is a short code-like name of the parameter (typically lowercase);

  • long_name is a more descriptive name, properly capitalized and localized if possible;

  • type is it’s type. Please see the MetaBuilder::ParameterType for a better description of what is a type;

  • desc is a proper (short) description of the parameter, something that would fit on a What’s this box, for instance.

  • attrs are optional parameters that may come useful, see Parameter#attributes documentation.

You might want to use the #param_reader, #param_writer, and #param_accessor facilities that create the respective accessors in addition. A typical example would be:

param :set_size, :size, 'size', "Size", {:type => :integer},
"The size !!"


335
336
337
338
339
340
341
342
343
# File 'lib/ctioga2/data/backends/description.rb', line 335

def param(writer, reader, name, long_name, type, 
          desc = "")
  raise "Use describe first" if description.nil? 
  param = nil
  param = Parameter.new(name, writer, reader,
                        long_name, type, desc)
  description.add_param(param)
  return param
end

#param_accessor(symbol, name, long_name, type, desc = "") ⇒ Object

The same as #param_writer, except that an attr_writer is created for the symbol instead of only a attr_writer. The most useful of the four methods. Typical use:

param_accessor :name, 'name', "Object name", {:type => :string},
"The name of the object"


368
369
370
371
372
373
# File 'lib/ctioga2/data/backends/description.rb', line 368

def param_accessor(symbol, name, long_name, type, 
                   desc = "")
  writer = (symbol.to_s + '=').to_sym
  attr_accessor symbol
  return param(writer, symbol, name, long_name, type, desc)
end

#param_reader(writer, reader, name, long_name, type, desc = "") ⇒ Object

The same as #param, but creates a attr_reader in addition



346
347
348
349
350
# File 'lib/ctioga2/data/backends/description.rb', line 346

def param_reader(writer, reader, name, long_name, type, 
                 desc = "")
  attr_reader reader
  return param(writer, reader, name, long_name, type, desc)
end

#param_writer(symbol, name, long_name, type, desc = "") ⇒ Object

The same as #param, except that writer is made from symbol by appending a = at the end. An attr_writer is created for the symbol.



355
356
357
358
359
360
# File 'lib/ctioga2/data/backends/description.rb', line 355

def param_writer(symbol, name, long_name, type, 
                 desc = "")
  writer = (symbol.to_s + '=').to_sym
  attr_writer symbol
  return param(writer, symbol, name, long_name, type, desc)
end

#register_class(desc = nil) ⇒ Object

Registers the given description to the factory. If no description is given, the current class is registered.



291
292
293
294
295
296
297
# File 'lib/ctioga2/data/backends/description.rb', line 291

def register_class(desc = nil)
  raise "One of the superclasses should have a 'factory' statement" unless
    has_factory?
  desc = description if desc.nil?
  factory_description_list << desc
  factory_description_hash[desc.name] = desc
end

#set_description(desc) ⇒ Object

Sets the description of the class. It is probably way better to use #describe, or write your own class method in the base class in the case of a family of classes.



307
308
309
310
311
312
# File 'lib/ctioga2/data/backends/description.rb', line 307

def set_description(desc)
  @description = desc
  if has_factory? and factory.private_auto_register
    register_class
  end
end