lib/hamster/hash.rb
require 'hamster/trie' module Hamster def self.hash(pairs = {}) pairs.reduce(Hash.new) { |hash, pair| hash.put(pair.first, pair.last) } end class Hash def initialize(trie = Trie.new) @trie = trie end def size @trie.size end alias_method :length, :size def empty? @trie.empty? end alias_method :null?, :empty? def has_key?(key) @trie.has_key?(key) end alias_method :key?, :has_key? alias_method :include?, :has_key? alias_method :member?, :has_key? def get(key) entry = @trie.get(key) if entry entry.value end end alias_method :[], :get def put(key, value) self.class.new(@trie.put(key, value)) end alias_method :[]=, :put def remove(key) trie = @trie.remove(key) if trie.equal?(@trie) self else self.class.new(trie) end end def each return self unless block_given? @trie.each { |entry| yield(entry.key, entry.value) } self end def map return self unless block_given? if empty? self else self.class.new(@trie.reduce(Trie.new) { |trie, entry| trie.put(*yield(entry.key, entry.value)) }) end end alias_method :collect, :map def reduce(memo) return memo unless block_given? @trie.reduce(memo) { |memo, entry| yield(memo, entry.key, entry.value) } end alias_method :inject, :reduce alias_method :fold, :reduce def filter return self unless block_given? trie = @trie.filter { |entry| yield(entry.key, entry.value) } if trie.equal?(@trie) self else self.class.new(trie) end end alias_method :select, :filter alias_method :find_all, :filter def reject return self unless block_given? select { |key, value| !yield(key, value) } end alias_method :delete_if, :reject def any? if block_given? each { |key, value| return true if yield(key, value) } else return !empty? end false end alias_method :exist?, :any? alias_method :exists?, :any? def all? if block_given? each { |key, value| return false unless yield(key, value) } end true end def none? if block_given? each { |key, value| return false if yield(key, value) } else return empty? end true end def eql?(other) other.is_a?(self.class) && @trie.eql?(other.instance_eval{@trie}) end alias_method :==, :eql? def dup self end alias_method :clone, :dup end end