class Rash

A Regex-queryable Hash.

Usage:

greeting = Rash.new( /^Mr./ => "Hello sir!", /^Mrs./ => "Evening, madame." )
greeting["Mr. Steve Austin"] #=> "Hello sir!"
greeting["Mrs. Steve Austin"] #=> "Evening, madame."

Attributes

optimize_every[RW]

Public Class Methods

new(initial) click to toggle source
# File lib/epitools/rash.rb, line 14
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/epitools/rash.rb, line 46
def [](key)
  all(key).first
end
[]=(key, value) click to toggle source
# File lib/epitools/rash.rb, line 32
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/epitools/rash.rb, line 53
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!
    @regexes.each do |regex|
      if match = regex.match(query)
        @regex_counts[regex] += 1
        value = @hash[regex]
        if value.responds_to? :call
          yield value.call(match)
        else
          yield value
        end
      end
    end

  when Integer
    @ranges.each do |range|
      yield @hash[range] if range.include? query
    end

  when Regexp
    # TODO: this doesn't seem very useful. should I ditch it? let me know!
    @hash.each do |key,val|
      yield val if key.is_a? String and query =~ key
    end

  end

end
method_missing(*args, &block) click to toggle source
# File lib/epitools/rash.rb, line 91
def method_missing(*args, &block)
  @hash.send(*args, &block)
end
update(other) click to toggle source
# File lib/epitools/rash.rb, line 25
def update(other)
  for key, value in other
    self[key] = value
  end
  self
end

Private Instance Methods

optimize_if_necessary!() click to toggle source
# File lib/epitools/rash.rb, line 97
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