summaryrefslogtreecommitdiff
path: root/lib/hashie/extensions/strict_key_access.rb
diff options
context:
space:
mode:
authorPeter Boling <peter.boling@gmail.com>2015-10-23 09:53:42 -0700
committerPeter Boling <peter.boling@gmail.com>2015-10-23 09:53:42 -0700
commit61b76fab81f9b876a3bdd7239b8509d2b69dd625 (patch)
tree80ef78e8fad669eb652ba3c8026fbdaa3189eae7 /lib/hashie/extensions/strict_key_access.rb
parentf0e5eac1997946975c447b388889dd9675b41ce9 (diff)
downloadhashie-61b76fab81f9b876a3bdd7239b8509d2b69dd625.tar.gz
SRP: The StrictKeyAccess extension will raise an error whenever a key is accessed that does not exist in the hash.
In Python a "Hash" is called a "Dictionary", and ... > "It is an error to extract a value using a non-existent key." See: https://docs.python.org/2/tutorial/datastructures.html#dictionaries EXAMPLE: class StrictHash < Hash include Hashie::Extensions::StrictKeyAccess end >> hash = StrictHash[foo: "bar"] => {:foo=>"bar"} >> hash[:foo] => "bar" >> hash[:cow] KeyError: key not found: :cow
Diffstat (limited to 'lib/hashie/extensions/strict_key_access.rb')
-rw-r--r--lib/hashie/extensions/strict_key_access.rb71
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/hashie/extensions/strict_key_access.rb b/lib/hashie/extensions/strict_key_access.rb
new file mode 100644
index 0000000..6972252
--- /dev/null
+++ b/lib/hashie/extensions/strict_key_access.rb
@@ -0,0 +1,71 @@
+module Hashie
+ module Extensions
+ # SRP: This extension will fail an error whenever a key is accessed that does not exist in the hash.
+ #
+ # EXAMPLE:
+ #
+ # class StrictKeyAccessHash < Hash
+ # include Hashie::Extensions::StrictKeyAccess
+ # end
+ #
+ # >> hash = StrictKeyAccessHash[foo: "bar"]
+ # => {:foo=>"bar"}
+ # >> hash[:foo]
+ # => "bar"
+ # >> hash[:cow]
+ # KeyError: key not found: :cow
+ #
+ # NOTE: For googlers coming from Python to Ruby, this extension makes a Hash behave like a "Dictionary".
+ #
+ module StrictKeyAccess
+ class DefaultError < StandardError
+ def initialize(msg = 'Setting or using a default with Hashie::Extensions::StrictKeyAccess does not make sense', *args)
+ super
+ end
+ end
+
+ # NOTE: This extension would break the default behavior of Hash initialization:
+ #
+ # >> a = StrictKeyAccessHash.new(a: :b)
+ # => {}
+ # >> a[:a]
+ # KeyError: key not found: :a
+ #
+ # Includes the Hashie::Extensions::MergeInitializer extension to get around that problem.
+ # Also note that defaults still don't make any sense with a StrictKeyAccess.
+ def self.included(base)
+ # Can only include into classes with a hash initializer
+ base.send(:include, Hashie::Extensions::MergeInitializer)
+ end
+
+ def [](key)
+ fetch(key)
+ end
+
+ def default(_ = nil)
+ fail DefaultError
+ end
+
+ def default=(_)
+ fail DefaultError
+ end
+
+ def default_proc
+ fail DefaultError
+ end
+
+ def default_proc=(_)
+ fail DefaultError
+ end
+
+ def key(value)
+ result = super
+ if result.nil? && (!key?(result) || self[result] != value)
+ fail KeyError, "key not found with value of #{value.inspect}"
+ else
+ result
+ end
+ end
+ end
+ end
+end