Class: Hashie::Rash
- Inherits:
-
Object
- Object
- Hashie::Rash
- Defined in:
- lib/hashie/rash.rb
Overview
Rash is a Hash whose keys can be Regexps, or Ranges, which will match many input keys.
A good use case for this class is routing URLs in a web framework. The Rash's keys match URL patterns, and the values specify actions which can handle the URL. When the Rash's value is proc, the proc will be automatically called with the regexp's matched groups as block arguments.
Usage example:
greeting = Hashie::Rash.new( /^Mr./ => "Hello sir!", /^Mrs./ => "Evening, madame." )
greeting["Mr. Steve Austin"] #=> "Hello sir!"
greeting["Mrs. Steve Austin"] #=> "Evening, madame."
Note: The Rash is automatically optimized every 500 accesses
(Regexps get sorted by how often they get matched).
If this is too low or too high, you can tune it by
setting: rash.optimize_every = n
Instance Attribute Summary collapse
-
#optimize_every ⇒ Object
Returns the value of attribute optimize_every.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Return the first thing that matches the key.
- #[]=(key, value) ⇒ Object
-
#all(query) ⇒ Object
Return everything that matches the query.
-
#fetch(*args) ⇒ Object
Raise (or yield) unless something matches the key.
-
#initialize(initial = {}) ⇒ Rash
constructor
A new instance of Rash.
- #method_missing(*args, &block) ⇒ Object
- #respond_to_missing?(method_name, _include_private = false) ⇒ Boolean
- #update(other) ⇒ Object
Constructor Details
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(*args, &block) ⇒ Object
127 128 129 |
# File 'lib/hashie/rash.rb', line 127 def method_missing(*args, &block) @hash.send(*args, &block) || super end |
Instance Attribute Details
#optimize_every ⇒ Object
Returns the value of attribute optimize_every.
24 25 26 |
# File 'lib/hashie/rash.rb', line 24 def optimize_every @optimize_every end |
Instance Method Details
#[](key) ⇒ Object
Return the first thing that matches the key.
59 60 61 |
# File 'lib/hashie/rash.rb', line 59 def [](key) all(key).first end |
#[]=(key, value) ⇒ Object
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/hashie/rash.rb', line 45 def []=(key, value) case key when Regexp # key = normalize_regex(key) # this used to just do: /#{regexp}/ @regexes << key when Range @ranges << key end @hash[key] = value end |
#all(query) ⇒ Object
Return everything that matches the query.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/hashie/rash.rb', line 88 def all(query) return to_enum(:all, query) unless block_given? if @hash.include? query yield @hash[query] return end case query when String optimize_if_necessary! # see if any of the regexps match the string @regexes.each do |regex| match = regex.match(query) next unless match @regex_counts[regex] += 1 value = @hash[regex] if value.respond_to? :call yield value.call(match) else yield value end end when Numeric # see if any of the ranges match the integer @ranges.each do |range| yield @hash[range] if range.cover? query end when Regexp # Reverse operation: `rash[/regexp/]` returns all string keys matching the regexp @hash.each do |key, val| yield val if key.is_a?(String) && query =~ key end end end |
#fetch(*args) ⇒ Object
Raise (or yield) unless something matches the key.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/hashie/rash.rb', line 66 def fetch(*args) raise ArgumentError, "Expected 1-2 arguments, got #{args.length}" \ unless (1..2).cover?(args.length) key, default = args all(key) do |value| return value end if block_given? yield key elsif default default else raise KeyError, "key not found: #{key.inspect}" end end |
#respond_to_missing?(method_name, _include_private = false) ⇒ Boolean
131 132 133 |
# File 'lib/hashie/rash.rb', line 131 def respond_to_missing?(method_name, _include_private = false) @hash.respond_to?(method_name) end |
#update(other) ⇒ Object
37 38 39 40 41 42 43 |
# File 'lib/hashie/rash.rb', line 37 def update(other) other.each do |key, value| self[key] = value end self end |