# File lib/model.rb, line 58
  def self.field name, opts={}
    @fields ||= [] # can't use a hash because we need to preserve field order
    raise ModelError, "field with name #{name} already defined" if @fields.any? { |k, v| k == name }
    @fields << [name, opts]

    if opts[:multi]
      single_name = name.to_s.sub(/s$/, "") # oh yeah
      define_method "add_#{single_name}" do |obj|
        array = send(name)
        raise ModelError, "already has a #{single_name} with name #{obj.name.inspect}" if obj.respond_to?(:name) && array.any? { |o| o.name == obj.name }
        changed!
        @serialized_values.delete name
        array << obj
      end

      define_method "drop_#{single_name}" do |obj|
        return unless @values[name].delete obj
        @serialized_values.delete name
        changed!
        obj
      end
    end

    define_method "#{name}=" do |o|
      changed!
      @serialized_values.delete name
      @values[name] = o
    end

    define_method "__serialized_#{name}=" do |o|
      changed!
      @values.delete name
      @serialized_values[name] = o
    end

    define_method "__serialized_#{name}" do
      @serialized_values[name]
    end

    define_method name do
      return @values[name] if @values.member?(name)
      @values[name] = deserialized_form_of name, @serialized_values[name]
    end
  end