Permalink
Browse files

Remove hashie as a real dep for now.

  • Loading branch information...
1 parent 53821ff commit 5b0cb21e9ae00d68cf88635a41be0c1631372dcd @joshbuddy committed Feb 2, 2012
Showing with 112 additions and 3 deletions.
  1. +0 −1 Gemfile
  2. +1 −1 data_bindings.gemspec
  3. +1 −1 lib/data_bindings.rb
  4. +110 −0 lib/ext/hashie.rb
View
@@ -1,4 +1,3 @@
source :rubygems
gemspec
-gem 'hashie', :git => 'https://github.com/intridea/hashie.git'
View
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
- s.add_runtime_dependency 'hashie', '= 2.0.0.beta'
+ # s.add_runtime_dependency 'hashie', '= 2.0.0.beta' NOTE: re-add after this is really published
# specify any dependencies here; for example:
s.add_development_dependency 'bson'
View
@@ -1,4 +1,4 @@
-require 'hashie'
+require 'ext/hashie'
require 'data_bindings/util'
require 'data_bindings/generator'
View
@@ -0,0 +1,110 @@
+module Hashie
+ module Extensions
+ # IndifferentAccess gives you the ability to not care
+ # whether your hash has string or symbol keys. Made famous
+ # in Rails for accessing query and POST parameters, this
+ # is a handy tool for making sure your hash has maximum
+ # utility.
+ #
+ # One unique feature of this mixin is that it will recursively
+ # inject itself into sub-hash instances without modifying
+ # the actual class of the sub-hash.
+ #
+ # @example
+ # class MyHash < Hash
+ # include Hashie::Extensions::MergeInitializer
+ # include Hashie::Extensions::IndifferentAccess
+ # end
+ #
+ # h = MyHash.new(:foo => 'bar', 'baz' => 'blip')
+ # h['foo'] # => 'bar'
+ # h[:foo] # => 'bar'
+ # h[:baz] # => 'blip'
+ # h['baz'] # => 'blip'
+ #
+ module IndifferentAccess
+ def self.included(base)
+ base.class_eval do
+ alias_method :regular_writer, :[]=
+ alias_method :[]=, :indifferent_writer
+ %w(default update fetch delete key? values_at).each do |m|
+ alias_method "regular_#{m}", m
+ alias_method m, "indifferent_#{m}"
+ end
+ end
+ end
+
+ # This will inject indifferent access into an instance of
+ # a hash without modifying the actual class. This is what
+ # allows IndifferentAccess to spread to sub-hashes.
+ def self.inject!(hash)
+ (class << hash; self; end).send :include, Hashie::Extensions::IndifferentAccess
+ hash.convert!
+ end
+
+ # Injects indifferent access into a duplicate of the hash
+ # provided. See #inject!
+ def self.inject(hash)
+ inject!(hash.dup)
+ end
+
+ def convert_key(key)
+ key.to_s
+ end
+
+ # Iterates through the keys and values, reconverting them to
+ # their proper indifferent state. Used when IndifferentAccess
+ # is injecting itself into member hashes.
+ def convert!
+ keys.each do |k|
+ regular_writer convert_key(k), convert_value(self.regular_delete(k))
+ end
+ self
+ end
+
+ def convert_value(value)
+ if hash_lacking_indifference?(value)
+ Hashie::Extensions::IndifferentAccess.inject(value.dup)
+ elsif value.is_a?(::Array)
+ value.dup.replace(value.map { |e| convert_value(e) })
+ else
+ value
+ end
+ end
+
+ def indifferent_default(key = nil)
+ return self[convert_key(key)] if key?(key)
+ regular_default(key)
+ end
+
+ def indifferent_update(other_hash)
+ return regular_update(other_hash) if hash_with_indifference?(other_hash)
+ other_hash.each_pair do |k,v|
+ self[k] = v
+ end
+ end
+
+ def indifferent_writer(key, value); regular_writer convert_key(key), convert_value(value) end
+ def indifferent_fetch(key, *args); regular_fetch convert_key(key), *args end
+ def indifferent_delete(key); regular_delete convert_key(key) end
+ def indifferent_key?(key); regular_key? convert_key(key) end
+ def indifferent_values_at(*indices); indices.map{|i| self[i] } end
+
+ def indifferent_access?; true end
+
+ protected
+
+ def hash_lacking_indifference?(other)
+ other.is_a?(::Hash) &&
+ !(other.respond_to?(:indifferent_access?) &&
+ other.indifferent_access?)
+ end
+
+ def hash_with_indifference?(other)
+ other.is_a?(::Hash) &&
+ other.respond_to?(:indifferent_access?) &&
+ other.indifferent_access?
+ end
+ end
+ end
+end

0 comments on commit 5b0cb21

Please sign in to comment.