Class: SDL::Receivers::TypeInstanceReceiver
- Defined in:
- lib/sdl/receivers/type_instance_receiver.rb
Overview
Receiver for setting the properties of Type instances
Instance Attribute Summary collapse
-
#instance ⇒ Object
Returns the value of attribute instance.
Attributes inherited from Receiver
Instance Method Summary collapse
- #annotation(value) ⇒ Object
-
#initialize(type_instance, compendium) ⇒ TypeInstanceReceiver
constructor
When initialized for a fact or type instance, the receiver creates singleton methods on itself for all properties.
-
#method_missing(name, *args) ⇒ Object
Catches calls to methods named similarily to possible predefined type instances.
Methods inherited from Receiver
Constructor Details
#initialize(type_instance, compendium) ⇒ TypeInstanceReceiver
When initialized for a fact or type instance, the receiver creates singleton methods on itself for all properties.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 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/sdl/receivers/type_instance_receiver.rb', line 9 def initialize(type_instance, compendium) super(compendium) @instance = type_instance type_instance.class.properties(true).each do |property| if property.single? # Single valued properties are set by their name define_singleton_method property.name do |value = nil, &block| if value.is_a? Symbol value = compendium.type_instances[property.type][value] || raise("Could not find instance :#{value.to_s} in predefined #{property.type.name} types") end begin type_instance.send "#{property.name}=", value rescue RuntimeError => e raise RuntimeError, "Cannot set property '#{property.name}' of Type #{@instance.class.name}: #{e}", e.backtrace end end else # Multi-valued properties are added to by their singular name, e.g. 'browsers' is set by invoking 'browser' define_singleton_method property.name.singularize do |*property_values, &block| existing_list = type_instance.send "#{property.name}" # If there is just one parameter for a multi-valued property setter if property_values.length == 1 # It could be a symbol, which would resolve to a predefined type instance of the same name if property_values[0].is_a?(Symbol) predefined_value = compendium.type_instances[property.type][property_values[0]] raise "Could not find instance :#{property_values[0]} in predefined #{property.type.name} types" unless predefined_value existing_list << compendium.type_instances[property.type][property_values[0]] # Or better: it could already be an instance of the type - e.g. when using the implemented #method_mssing elsif property_values[0].is_a? property.type existing_list << property_values[0] property_values[0].parent_index = existing_list.count - 1 unless property_values[0].identifier else raise "Type #{property_values[0].class} of list item '#{property_values}' is incompatible with list type #{property.type}." end else new_list_item = property.type.new set_value(property.type, new_list_item, *property_values) SDL::Receivers::TypeInstanceReceiver.new(new_list_item, @compendium).instance_exec(&block) unless block.nil? existing_list << new_list_item new_list_item.parent = type_instance new_list_item.parent_index = existing_list.count - 1 end end end end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
Catches calls to methods named similarily to possible predefined type instances
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/sdl/receivers/type_instance_receiver.rb', line 73 def method_missing(name, *args) # Possible type instances are all types of properties of properties of this instance ... possible_type_classes = @instance.class.properties.map(&:type).map(&:properties).flatten.map(&:type).select{|type| type.wrapped_type < SDL::Base::Type} # ... and the types of multi-value instances possible_type_classes.concat(@instance.class.properties.find_all{|p| p.multi?}.map(&:type)) possible_type_instances = @compendium.type_instances.select{|k, v| possible_type_classes.include?(k)}.map{|k, v| v[name]}.select{|v| v != nil} unless possible_type_instances.nil? || possible_type_instances.empty? possible_type_instances[0] else raise Exception.new("I do not know what to do with '#{name}' in #{caller[0]}") end end |
Instance Attribute Details
#instance ⇒ Object
Returns the value of attribute instance.
4 5 6 |
# File 'lib/sdl/receivers/type_instance_receiver.rb', line 4 def instance @instance end |
Instance Method Details
#annotation(value) ⇒ Object
67 68 69 |
# File 'lib/sdl/receivers/type_instance_receiver.rb', line 67 def annotation(value) @instance.annotations << value end |