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



258
259
260
261
262
263
264
# File 'lib/ctioga2/data/backends/description.rb', line 258

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.



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

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.



380
381
382
383
# File 'lib/ctioga2/data/backends/description.rb', line 380

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

#descriptionObject

Returns the Description of the class.



303
304
305
# File 'lib/ctioga2/data/backends/description.rb', line 303

def description
  return @description
end

#factory_class(name) ⇒ Object

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



288
289
290
# File 'lib/ctioga2/data/backends/description.rb', line 288

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

#factory_description(name) ⇒ Object

Returns the factory description with the given name



281
282
283
284
# File 'lib/ctioga2/data/backends/description.rb', line 281

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



275
276
277
278
# File 'lib/ctioga2/data/backends/description.rb', line 275

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



268
269
270
271
# File 'lib/ctioga2/data/backends/description.rb', line 268

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)


252
253
254
# File 'lib/ctioga2/data/backends/description.rb', line 252

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.



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

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


338
339
340
341
342
343
344
345
346
# File 'lib/ctioga2/data/backends/description.rb', line 338

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"


371
372
373
374
375
376
# File 'lib/ctioga2/data/backends/description.rb', line 371

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



349
350
351
352
353
# File 'lib/ctioga2/data/backends/description.rb', line 349

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.



358
359
360
361
362
363
# File 'lib/ctioga2/data/backends/description.rb', line 358

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.



294
295
296
297
298
299
300
# File 'lib/ctioga2/data/backends/description.rb', line 294

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.



310
311
312
313
314
315
# File 'lib/ctioga2/data/backends/description.rb', line 310

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