middleman/middleman-core/lib/middleman-core/util/hash_with_indifferent_access.rb
Steven Sloan 14e1cb1cd6 move all HashWithIndifferentAccess recursive enhancement over to the Util class
TODO: moving this two a class method on HashWithIndifferentAccess would really make the most sense, but there are two blockers:
- historically the method has operated out of Util. While totally ok, simply dedeferring to HashWithIndifferentAccess feels a bit awkward
- the contracts gem doesn’t support class method at this time. the assurance of frozen output is important considering the uses of the recursively_enhance method
2015-01-15 03:30:26 -05:00

88 lines
1.9 KiB
Ruby

require 'middleman-core/contracts'
module Middleman
module Util
# A hash with indifferent access and magic predicates.
# Copied from Thor
#
# hash = Middleman::Util::HashWithIndifferentAccess.new 'foo' => 'bar', 'baz' => 'bee', 'force' => true
#
# hash[:foo] #=> 'bar'
# hash['foo'] #=> 'bar'
# hash.foo? #=> true
#
class HashWithIndifferentAccess < ::Hash #:nodoc:
include Contracts
Contract Hash => Any
def initialize(hash={})
super()
hash.each do |key, val|
self[key] = Util.recursively_enhance(val)
end
freeze
end
def [](key)
super(convert_key(key))
end
def []=(key, value)
super(convert_key(key), value)
end
def delete(key)
super(convert_key(key))
end
def values_at(*indices)
indices.map { |key| self[convert_key(key)] }
end
def merge(other)
dup.merge!(other)
end
def merge!(other)
other.each do |key, value|
self[convert_key(key)] = value
end
self
end
# Convert to a Hash with String keys.
def to_hash
Hash.new(default).merge!(self)
end
protected
def convert_key(key)
key.is_a?(Symbol) ? key.to_s : key
end
# Magic predicates. For instance:
#
# options.force? # => !!options['force']
# options.shebang # => "/usr/lib/local/ruby"
# options.test_framework?(:rspec) # => options[:test_framework] == :rspec
# rubocop:disable DoubleNegation
def method_missing(method, *args)
method = method.to_s
if method =~ /^(\w+)\?$/
if args.empty?
!!self[$1]
else
self[$1] == args.first
end
else
self[method]
end
end
end
end
end