Module: Collapsium::IndifferentAccess
- Extended by:
- Support::Methods
- Included in:
- UberHash
- Defined in:
- lib/collapsium/indifferent_access.rb
Overview
Provides indifferent access to string/symbol keys in a Hash. That is, if your hash contains a string key, you can also access it via a symbol and vice versa.
Constant Summary collapse
- METHODS =
( ::Collapsium::Support::HashMethods::KEYED_READ_METHODS \ + ::Collapsium::Support::HashMethods::KEYED_WRITE_METHODS ).freeze
- INDIFFERENT_ACCESS =
proc do |wrapped_method, *args, &block| # Bail out early if the receiver is not a Hash. Do the same if we have # no key. receiver = wrapped_method.receiver if not receiver.is_a? Hash or args.empty? next wrapped_method.call(*args, &block) end # Definitely try the key as given first. Then, depending on the key's # type and value, we want to try it as a Symbol, String and/or Integer key = args.shift tries = IndifferentAccess.key_permutations(key) # With the variations to try assembled, go through them one by one. We # define an inner class here for undefined results because 'nil' can be # a legitimate result from the wrapped method. class Undefined; end result = Undefined tries.each do |try| if receiver.keys.include?(try) result = wrapped_method.call(try, *args, &block) break end end # If any of the above yielded a result, great, return that. Otherwise # yield to the default implementation (i.e. wrapped_method). if result != Undefined next result end next wrapped_method.call(key, *args, &block) end.freeze
Constants included from Support::Methods
Support::Methods::BUILTINS, Support::Methods::WRAPPER_HASH
Class Method Summary collapse
- .enhance(base) ⇒ Object
- .extended(base) ⇒ Object
- .included(base) ⇒ Object
-
.key_permutations(key) ⇒ Object
Given a key, returns all indifferent permutations to try.
- .prepended(base) ⇒ Object
-
.sorted_keys(keys, &block) ⇒ Object
Sort the given keys indifferently.
-
.unique_keys(keys) ⇒ Object
Make the given keys unique according to the logic of this module.
Methods included from Support::Methods
builtins, loop_detected?, repeated, resolve_helpers, wrap_method, wrappers
Class Method Details
.enhance(base) ⇒ Object
124 125 126 127 128 129 130 131 132 133 |
# File 'lib/collapsium/indifferent_access.rb', line 124 def enhance(base) # Make the capabilities of classes using IndifferentAccess viral. base.extend(ViralCapabilities) # Wrap all accessor functions to deal with paths METHODS.each do |method| wrap_method(base, method, raise_on_missing: false, &INDIFFERENT_ACCESS) end end |
.extended(base) ⇒ Object
116 117 118 |
# File 'lib/collapsium/indifferent_access.rb', line 116 def extended(base) enhance(base) end |
.included(base) ⇒ Object
112 113 114 |
# File 'lib/collapsium/indifferent_access.rb', line 112 def included(base) enhance(base) end |
.key_permutations(key) ⇒ Object
Given a key, returns all indifferent permutations to try.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/collapsium/indifferent_access.rb', line 31 def key_permutations(key) tries = [key] if key.is_a? Symbol key_s = key.to_s tries << key_s if key_s =~ /^[0-9]/ tries << key_s.to_i end elsif key.is_a? String tries << key.to_sym if key =~ /^[0-9]/ tries << key.to_i end elsif key.is_a? Integer tries += [key.to_s, key.to_s.to_sym] end return tries end |
.prepended(base) ⇒ Object
120 121 122 |
# File 'lib/collapsium/indifferent_access.rb', line 120 def prepended(base) enhance(base) end |
.sorted_keys(keys, &block) ⇒ Object
Sort the given keys indifferently. This will sort Integers first, Symbols second and Strings third. Everything else comes last. This is done because that’s the order in which comparsion time increases.
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/collapsium/indifferent_access.rb', line 63 def sorted_keys(keys, &block) # Sorting sucks because we can't compare Strings and Symbols. So in # order to get this right, we'll have to sort each type individually, # then concatenate the results. sorted = [] [Integer, Symbol, String].each do |klass| sorted += keys.select { |key| key.is_a?(klass) }.sort(&block) end return sorted end |
.unique_keys(keys) ⇒ Object
Make the given keys unique according to the logic of this module.
53 54 55 56 57 |
# File 'lib/collapsium/indifferent_access.rb', line 53 def unique_keys(keys) # The simplest way is to stringify all keys before making them # unique. That works for Integer as well as Symbol. return keys.map(&:to_s).uniq end |