class Hashie::Rash


setting: ‘rash.optimize_every = n`
If this is too low or too high, you can tune it by
(Regexps get sorted by how often they get matched).
Note: The Rash is automatically optimized every 500 accesses
greeting[“Mrs. Steve Austin”] #=> “Evening, madame.”
greeting[“Mr. Steve Austin”] #=> “Hello sir!”
greeting = Hashie::Rash.new( /^Mr./ => “Hello sir!”, /^Mrs./ => “Evening, madame.” )
Usage example:
block arguments.
will be automatically called with the regexp’s matched groups as
which can handle the URL. When the Rash’s value is proc, the proc
The Rash’s keys match URL patterns, and the values specify actions
A good use case for this class is routing URLs in a web framework.
match many input keys.
Rash is a Hash whose keys can be Regexps, or Ranges, which will

def [](key)


Return the first thing that matches the key.
def [](key)
  all(key).first
end

def []=(key, value)

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

def all(query)


Return everything that matches the query.
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)
      if match
        @regex_counts[regex] += 1
        value = @hash[regex]
        if value.respond_to? :call
          yield value.call(match)
        else
          yield value
        end
      end
    end
  when Integer
    # see if any of the ranges match the integer
    @ranges.each do |range|
      yield @hash[range] if range.include? query
    end
  when Regexp
    # Reverse operation: `rash[/regexp/]` returns all the hash's string keys which match the regexp
    @hash.each do |key, val|
      yield val if key.is_a?(String) && query =~ key
    end
  end
end

def initialize(initial = {})

def initialize(initial = {})
  @hash           = {}
  @regexes        = []
  @ranges         = []
  @regex_counts   = Hash.new(0)
  @optimize_every = 500
  @lookups        = 0
  update(initial)
end

def method_missing(*args, &block)

def method_missing(*args, &block)
  @hash.send(*args, &block)
end

def optimize_if_necessary!

def optimize_if_necessary!
  if (@lookups += 1) >= @optimize_every
    @regexes = @regex_counts.sort_by { |regex, count| -count }.map { |regex, count| regex }
    @lookups = 0
  end
end

def update(other)

def update(other)
  other.each do |key, value|
    self[key] = value
  end
  self
end