Module: MetaBuilder::DescriptionExtend

Included in:
CTioga::PlotMaker, SciYAG::Backends::Backend
Defined in:
lib/MetaBuilder/descriptions.rb

Overview

This module should be used with extend to provide the class with descriptions functionnalities. You also need to include DescriptionInclude. 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



441
442
443
444
445
446
447
# File 'lib/MetaBuilder/descriptions.rb', line 441

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.



407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/MetaBuilder/descriptions.rb', line 407

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.



566
567
568
569
# File 'lib/MetaBuilder/descriptions.rb', line 566

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

#descriptionObject

Returns the Description of the class.



486
487
488
# File 'lib/MetaBuilder/descriptions.rb', line 486

def description
  return @description
end

#factory_class(name) ⇒ Object

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



471
472
473
# File 'lib/MetaBuilder/descriptions.rb', line 471

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

#factory_description(name) ⇒ Object

Returns the factory description with the given name



464
465
466
467
# File 'lib/MetaBuilder/descriptions.rb', line 464

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



458
459
460
461
# File 'lib/MetaBuilder/descriptions.rb', line 458

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



451
452
453
454
# File 'lib/MetaBuilder/descriptions.rb', line 451

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

#group(name, long_name = name, desc = nil) ⇒ Object

Switches to the given ParameterGroup. If it doesn’t exist, it is created with the given parameters.



592
593
594
595
596
597
598
# File 'lib/MetaBuilder/descriptions.rb', line 592

def group(name, long_name = name, desc = nil)
  if not description.group_hash.has_key?(name)
    group = ParameterGroup.new(name, long_name, desc)
    description.add_group(group)
  end
  description.switch_to_group(name)
end

#has_factory?Boolean

Checks if the class has a factory

Returns:

  • (Boolean)


436
437
438
# File 'lib/MetaBuilder/descriptions.rb', line 436

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.



575
576
577
578
579
580
581
582
583
584
585
586
587
588
# File 'lib/MetaBuilder/descriptions.rb', line 575

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 = "", attrs = {}) ⇒ 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 !!"


522
523
524
525
526
527
528
529
530
# File 'lib/MetaBuilder/descriptions.rb', line 522

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

#param_accessor(symbol, name, long_name, type, desc = "", attrs = {}) ⇒ 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"


556
557
558
559
560
561
562
# File 'lib/MetaBuilder/descriptions.rb', line 556

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

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

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



533
534
535
536
537
538
# File 'lib/MetaBuilder/descriptions.rb', line 533

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

#param_writer(symbol, name, long_name, type, desc = "", attrs = {}) ⇒ 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.



542
543
544
545
546
547
548
# File 'lib/MetaBuilder/descriptions.rb', line 542

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

#register_class(desc = nil) ⇒ Object

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



477
478
479
480
481
482
483
# File 'lib/MetaBuilder/descriptions.rb', line 477

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.



493
494
495
496
497
498
# File 'lib/MetaBuilder/descriptions.rb', line 493

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