Class: Chione::Component

Inherits:
Object
  • Object
show all
Extended by:
MethodUtilities, Loggability, Pluggability
Includes:
Inspection
Defined in:
lib/chione/component.rb

Overview

The Component (data) class

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MethodUtilities

attr_predicate, attr_predicate_accessor, singleton_attr_accessor, singleton_attr_reader, singleton_attr_writer, singleton_method_alias, singleton_predicate_accessor, singleton_predicate_reader

Methods included from Inspection

#inspect

Constructor Details

#initialize(entity_id = nil, values = {}) ⇒ Component

Create a new component with the specified values.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/chione/component.rb', line 87

def initialize( entity_id=nil, values={} )
  if entity_id.is_a?( Hash )
    values = entity_id
    entity_id = nil
  end

  @entity_id = entity_id

  if self.class.fields
    self.class.fields.each_key do |name|
      val = values[ name ] || self.class.send( "default_for_#{name}" )
      self.public_send( "#{name}=", val )
    end
  end
end

Instance Attribute Details

#entity_idObject

The ID of the entity the component belongs to



110
111
112
# File 'lib/chione/component.rb', line 110

def entity_id
  @entity_id
end

Class Method Details

.field(name, **options, &process_block) ⇒ Object

Declare a field for the component named name, with a default value of default. If the optional process_block is provided, it will be called with the new value being assigned to the field before it is set, and the return value of it will be used instead.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/chione/component.rb', line 43

def self::field( name, **options, &process_block )
  options[ :processor ] = process_block
  self.fields ||= {}
  self.fields[ name ] = options

  # Add some class method
  self.define_singleton_method( "processor_for_#{name}" ) do
    return self.fields.dig( name, :processor )
  end
  self.define_singleton_method( "default_for_#{name}" ) do
    default = self.fields.dig( name, :default )
    return default.call( self ) if default.respond_to?( :call )
    return Chione::DataUtilities.deep_copy( default )
  end
  self.define_singleton_method( "options_for_#{name}" ) do
    return self.fields[ name ]
  end

  # Add instance methods as a mixin so they can be overridden and super()ed to
  mixin = self.make_field_mixin( name )
  self.include( mixin )

end

.inherited(subclass) ⇒ Object

Inheritance callback – add some default instance variable values to subclasses.



32
33
34
35
36
# File 'lib/chione/component.rb', line 32

def self::inherited( subclass )
  super

  subclass.fields ||= {}
end

.make_field_mixin(name) ⇒ Object

Make a mixin module with methods for the field with the specified name.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/chione/component.rb', line 69

def self::make_field_mixin( name )
  mixin = Module.new

  mixin.attr_reader( name )
  mixin.define_method( "process_#{name}" ) do |value|
    processor = self.class.send( "processor_for_#{name}" ) or return value
    return processor.call( value )
  end
  mixin.define_method( "#{name}=" ) do |new_val|
    new_val = self.send( "process_#{name}", new_val )
    self.instance_variable_set( "@#{name}", new_val )
  end

  return mixin
end

Instance Method Details

#fieldsObject

The Hash of fields implemented by the component



27
# File 'lib/chione/component.rb', line 27

singleton_attr_accessor :fields