module MR::JsonField::ClassMethods

Public Instance Methods

json_field(field_name, options = nil) click to toggle source
# File lib/mr/json_field.rb, line 40
def json_field(field_name, options = nil)
  json_field_reader(field_name, options)
  json_field_writer(field_name, options)
end
json_field_accessors() click to toggle source
# File lib/mr/json_field.rb, line 118
def json_field_accessors
  self.json_field_readers & self.json_field_writers
end
json_field_reader(field_name, options = nil) click to toggle source
# File lib/mr/json_field.rb, line 45
def json_field_reader(field_name, options = nil)
  options ||= {}
  field_name        = field_name.to_s
  ivar_name         = "@#{field_name}"
  source_field_name = (options[:source] || "#{field_name}_json").to_s

  if source_field_name == field_name
    raise ArgumentError, "the field name and source cannot be the same"
  end

  define_method(field_name) do
    if !(cached_value = self.instance_variable_get(ivar_name)).nil?
      return cached_value
    else
      source_value = self.send(source_field_name)
      return source_value if source_value.nil?

      value = begin
        MR::JsonField.decode(source_value)
      rescue InvalidJSONError => exception
        message = "can't decode `#{field_name}` JSON field (from " \
                  "`#{source_field_name}`): #{exception.message}"
        raise exception.class, message, caller
      end

      # cache the decoded value in the ivar
      self.instance_variable_set(ivar_name, value)

      value
    end
  end

  (self.json_field_readers       << field_name).uniq!
  (self.json_field_source_fields << source_field_name).uniq!
end
json_field_readers() click to toggle source
# File lib/mr/json_field.rb, line 115
def json_field_readers; @json_field_readers ||= []; end
json_field_source_fields() click to toggle source
# File lib/mr/json_field.rb, line 122
def json_field_source_fields
  @json_field_source_fields ||= []
end
json_field_writer(field_name, options = nil) click to toggle source
# File lib/mr/json_field.rb, line 81
def json_field_writer(field_name, options = nil)
  options ||= {}
  field_name        = field_name.to_s.strip
  ivar_name         = "@#{field_name}"
  source_field_name = (options[:source] || "#{field_name}_json").to_s.strip

  if source_field_name == field_name
    raise ArgumentError, "the field name and source cannot be the same"
  end

  define_method("#{field_name}=") do |new_value|
    encoded_value = if !new_value.nil?
      begin
        MR::JsonField.encode(new_value)
      rescue InvalidJSONError => exception
        message = "can't encode value for `#{field_name}` JSON field: " \
                  "#{exception.message}"
        raise exception.class, message, caller
      end
    else
      nil
    end
    self.send("#{source_field_name}=", encoded_value)

    # reset the ivar so its value will be calculated again when read
    self.instance_variable_set(ivar_name, nil)

    new_value
  end

  (self.json_field_writers       << field_name).uniq!
  (self.json_field_source_fields << source_field_name).uniq!
end
json_field_writers() click to toggle source
# File lib/mr/json_field.rb, line 116
def json_field_writers; @json_field_writers ||= []; end