Skip to content

Instantly share code, notes, and snippets.

@guyboertje
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guyboertje/acefa786bab1e974438e to your computer and use it in GitHub Desktop.
Save guyboertje/acefa786bab1e974438e to your computer and use it in GitHub Desktop.
Streaming Json parsing: implest class to build from Oj.saj_parse and JrJackson::Json.sj_parse
class SomeModel
def null(*) end
ATTRS = ['v_string', 'v_num', 'v_boolean', 'v_decimal']
attr_accessor *ATTRS.map(&:to_sym)
METHODMAP = Hash.new(instance_method(:null))
ATTRS.each {|attr| METHODMAP[attr] = instance_method("#{attr}=") }
def self.load(hash) new.load(hash); end
def load(hash)
@v_string, @v_num, @v_boolean, @v_decimal = hash.values_at(*ATTRS)
self
end
def add_value(value, key)
METHODMAP[key].bind(self).call(value)
end
def to_s
"<SomeModel @v_string: '#{v_string}', @v_num: #{v_num}, @v_boolean: #{v_boolean}, @v_decimal: #{v_decimal}"
end
end
sm = SomeModel.new #=> #<SomeModel:0x007f898145f878>
sm.add_value('foo','v_string') #=> "foo"
sm.to_s #=> "<SomeModel @v_string: 'foo', @v_num: , @v_boolean: , @v_decimal: "
sm.add_value('v_string','foo:') #=> nil
sm.to_s #=> "<SomeModel @v_string: 'foo', @v_num: , @v_boolean: , @v_decimal: "
json_source = %Q|{
"v_num": 3,
"v_decimal": 3.333,
"v_boolean" : true,
"v_string": "message"
}|
model = SomeModel.new
Oj.saj_parse(model, json_source)
model.to_s #=> "<SomeModel @v_string: 'message', @v_num: 3, @v_boolean: true, @v_decimal: 3.333"
@guyboertje
Copy link
Author

One could use Virtus or similar, but as this is part of a benchmark, I wanted a Model implementation that contributed as little overhead as possible.

This can be abstracted into a module that one can include in another class.
e.g.

class OtherModel
  include MinimalAttr.new('v_string', 'v_num', 'v_boolean', 'v_decimal')
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment