Skip to content

Instantly share code, notes, and snippets.

@sfcgeorge
Created April 11, 2017 10:17
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 sfcgeorge/e49024e6353ac6fde8a809cbd913661c to your computer and use it in GitHub Desktop.
Save sfcgeorge/e49024e6353ac6fde8a809cbd913661c to your computer and use it in GitHub Desktop.
Use JSON as a Ruby object like you just don't care, if you like OpenStruct you'll love JsonSlop!
require "json"
class JsonSlop
def initialize(json)
@hash = json.is_a?(String) ? JSON.parse(json) : json
end
def call
JsonSlopProxy.new(@hash)
end
def self.call(json)
new(json).call
end
class JsonSlopProxy < BasicObject
include ::Enumerable
def initialize(collection)
@collection = collection
end
def method_missing(key, *args, &block)
if @collection.respond_to?(key)
_json_slop_wrap key, @collection.send(key, *args, &block)
elsif @collection.key?(key.to_s)
_json_slop_wrap key, @collection[key.to_s]
else
super
end
end
def respond_to_missing?(key)
@collection.respond_to?(key) || @collection.key?(key.to_s)
end
def each
@collection.each { |v| yield _json_slop_wrap(v) }
end
private
def _json_slop_wrap(key = "", val)
if val.is_a?(::Hash) || val.is_a?(::Array) && !key.to_s.start_with?("to_")
JsonSlopProxy.new(val)
else
val
end
end
end
end
slop = JsonSlop.('{"results": [{ "stuff": "Hello" }, { "stuff": "World" }] }')
puts slop.results.map(&:stuff)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment