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



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

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.



219
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
# File 'lib/ctioga2/data/backends/description.rb', line 219

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.



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

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

#descriptionObject

Returns the Description of the class.



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

def description
  return @description
end

#factory_class(name) ⇒ Object

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



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

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

#factory_description(name) ⇒ Object

Returns the factory description with the given name



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

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



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

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



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

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)


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

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.



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

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 !!"


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

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"


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

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



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

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.



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

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.



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

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.



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

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