module UniverseCompiler module Entity module FieldManagement attr_accessor :auto_create_fields def method_missing(method_name, *args) if auto_create_fields candidate_field_name = method_name method_name.to_s.match (/^(?[^=]+)\s*=?$/) do |md| candidate_field_name = md['field_name'].to_sym end define_field_accessor candidate_field_name raise "Invalid method '#{method_name}' in #{self}" unless self.respond_to? method_name self.send method_name, *args else super(method_name, *args) end end private def define_known_fields_accessors self.class.fields_constraints.each do |field_name, constraints| define_field_accessor field_name if fields[field_name].nil? fields[field_name] = [] if constraints[:has_many] || constraints[:is_array] fields[field_name] = {} if constraints[:is_hash] end end end def define_field_accessor(field_name) metaclass = class << self; self ; end UniverseCompiler.logger.debug 'Defining field accessor %s on class %s (%s)' % [field_name, metaclass, self.type] define_field_reader(field_name, metaclass) define_field_writer(field_name, metaclass) end def define_field_writer(field_name, metaclass) if self.respond_to? "#{field_name}=" UniverseCompiler.logger.info "'#{field_name}=' already exists on class '#{metaclass}'. Skipped !" else metaclass.instance_eval do define_method "#{field_name}=" do |value| fields[field_name] = value end end end end def define_field_reader(field_name, metaclass) if self.respond_to? field_name UniverseCompiler.logger.info "'#{field_name}' already exists on class '#{metaclass}'. Skipped !" else metaclass.instance_eval do define_method field_name do fields[field_name] end end end end end end end