Skip to content

Instantly share code, notes, and snippets.

@jszmajda
Last active August 29, 2015 14:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jszmajda/08603f08f554c87268d5 to your computer and use it in GitHub Desktop.
Save jszmajda/08603f08f554c87268d5 to your computer and use it in GitHub Desktop.
Dot Notation
# Simple-ish enumberable-simplifier. Useful for APIs like Twitter, etc
#
# If you have a hash or an array or something that quacks like one, you can do stuff
# example:
# h = {a: {b: {c: [{d: 'hi'}]}}}
# h.extend(DotNotation)
# h.dot('a.b.c.0.d')
# #=> 'hi'
# h.dot('a.b.c.foo.bar.bz.whatever.124.whocares')
# #=> nil
#
module DotNotation
def self.included(base)
raise "Unsupported Class" unless base.respond_to?('[]')
end
def dot(path)
return nil if self.nil? # optimization for NilClass
data = self
path.split(/\./).each do |selector|
selector = selector.to_i if selector =~ /^\d+$/
if value = access(data, selector)
data = value
else
return nil
end
end
if @dot_options && @dot_options[:autodot]
extend_result!(data)
data.each{|e| extend_result!(e) } if data.kind_of? Array
end
data
end
def dot_options(options)
@dot_options = (@dot_options || {}).merge(options)
end
private
def extend_result!(result)
begin
result.extend(DotNotation)
result.dot_options(@dot_options)
rescue TypeError
# ignore, we get this when trying to extend an int or something
end
end
def access(data, selector)
if defined?(ActiveRecord::Base) && data.kind_of?(ActiveRecord::Base)
access_active_record(data, selector)
else
access_generic(data, selector)
end
end
def access_active_record(data, selector)
selsym = selector.respond_to?(:to_sym) ? selector.to_sym : nil
if selsym && data.respond_to?(selsym)
data.send(selsym)
else
access_generic(data, selector)
end
end
def access_generic(data, selector)
if data[selector]
data[selector]
else
selsym = selector.respond_to?(:to_sym) ? selector.to_sym : nil
if selsym && data[selsym]
data[selsym]
else
nil
end
end
end
end
@jszmajda
Copy link
Author

This will trash your method cache. Don't use unless you don't care

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