class Hashie::Rash
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`
Attributes
optimize_every[RW]
Public Class Methods
new(initial = {})
click to toggle source
# File lib/hashie/rash.rb, line 26 def initialize(initial = {}) @hash = {} @regexes = [] @ranges = [] @regex_counts = Hash.new(0) @optimize_every = 500 @lookups = 0 update(initial) end
Public Instance Methods
[](key)
click to toggle source
Return the first thing that matches the key.
# File lib/hashie/rash.rb, line 59 def [](key) all(key).first end
[]=(key, value)
click to toggle source
# 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) { |hash| ... }
click to toggle source
Return everything that matches the query.
# 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) { |key| ... }
click to toggle source
Raise (or yield) unless something matches the key.
# 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
method_missing(*args, &block)
click to toggle source
Calls superclass method
# File lib/hashie/rash.rb, line 127 def method_missing(*args, &block) @hash.send(*args, &block) || super end
respond_to_missing?(method_name, _include_private = false)
click to toggle source
# File lib/hashie/rash.rb, line 131 def respond_to_missing?(method_name, _include_private = false) @hash.respond_to?(method_name) end
update(other)
click to toggle source
# File lib/hashie/rash.rb, line 37 def update(other) other.each do |key, value| self[key] = value end self end
Private Instance Methods
optimize_if_necessary!()
click to toggle source
# File lib/hashie/rash.rb, line 137 def optimize_if_necessary! return unless (@lookups += 1) >= @optimize_every @regexes = @regexes.sort_by { |regex| -@regex_counts[regex] } @lookups = 0 end