diff options
author | Peter Boling <peter.boling@gmail.com> | 2015-10-23 09:53:42 -0700 |
---|---|---|
committer | Peter Boling <peter.boling@gmail.com> | 2015-10-23 09:53:42 -0700 |
commit | 61b76fab81f9b876a3bdd7239b8509d2b69dd625 (patch) | |
tree | 80ef78e8fad669eb652ba3c8026fbdaa3189eae7 /lib/hashie/extensions/strict_key_access.rb | |
parent | f0e5eac1997946975c447b388889dd9675b41ce9 (diff) | |
download | hashie-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.rb | 71 |
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 |