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
- READ_METHODS =
::Collapsium::Support::HashMethods::KEYED_READ_METHODS.freeze
- INDIFFERENT_ACCESS_READER =
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 result = nil 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 not result.nil? 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
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/collapsium/indifferent_access.rb', line 118 def enhance(base) # Make the capabilities of classes using IndifferentAccess viral. base.extend(ViralCapabilities) # Wrap all accessor functions to deal with paths READ_METHODS.each do |method| wrap_method(base, method, raise_on_missing: false, &INDIFFERENT_ACCESS_READER) end end |
.extended(base) ⇒ Object
110 111 112 |
# File 'lib/collapsium/indifferent_access.rb', line 110 def extended(base) enhance(base) end |
.included(base) ⇒ Object
106 107 108 |
# File 'lib/collapsium/indifferent_access.rb', line 106 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
114 115 116 |
# File 'lib/collapsium/indifferent_access.rb', line 114 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 |