Skip to content

Instantly share code, notes, and snippets.

@brentd
Created April 8, 2010 20:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save brentd/360506 to your computer and use it in GitHub Desktop.
Save brentd/360506 to your computer and use it in GitHub Desktop.
# Allows you to build a Hash in a fashion very similar to Builder. Example:
#
# HashBuilder.build! do |h|
# h.name "Brent"
# h.skillz true
# h.location do
# h.planet "Earth"
# end
# end
#
# produces:
#
# {:name => "Brent", :skillz => true, :location => {:planet => "Earth"}}
#
class HashBuilder
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|^object_id$)/ }
def initialize
@hash = {}
@target = @hash
end
def self.build!
builder = HashBuilder.new
yield builder
builder.to_h
end
def to_h
@hash
end
def inspect
to_h.inspect
end
def attr!(key, value=nil)
if block_given?
parent = @target
@target = {}
yield
parent[key] = @target
@target = parent
else
@target[key] = value
end
@hash
end
def method_missing(key, value=nil, &block)
attr!(key, value, &block)
end
end
class Hash
unless method_defined?(:build!)
def build!(&block)
::HashBuilder.build!(&block)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment