diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/vendor/rack-mount-0.6.6.pre/rack/mount/vendor/multimap/multimap.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/vendor/rack-mount-0.6.6.pre/rack/mount/vendor/multimap/multimap.rb | 569 |
1 files changed, 0 insertions, 569 deletions
diff --git a/actionpack/lib/action_dispatch/vendor/rack-mount-0.6.6.pre/rack/mount/vendor/multimap/multimap.rb b/actionpack/lib/action_dispatch/vendor/rack-mount-0.6.6.pre/rack/mount/vendor/multimap/multimap.rb deleted file mode 100644 index 0b49b49280..0000000000 --- a/actionpack/lib/action_dispatch/vendor/rack-mount-0.6.6.pre/rack/mount/vendor/multimap/multimap.rb +++ /dev/null @@ -1,569 +0,0 @@ -require 'forwardable' -require 'multiset' - -# Multimap is a generalization of a map or associative array -# abstract data type in which more than one value may be associated -# with and returned for a given key. -# -# == Example -# -# require 'multimap' -# map = Multimap.new -# map["a"] = 100 -# map["b"] = 200 -# map["a"] = 300 -# map["a"] # -> [100, 300] -# map["b"] # -> [200] -# map.keys # -> #<Multiset: {a, a, b}> -class Multimap - extend Forwardable - - include Enumerable - - # call-seq: - # Multimap[ [key =>|, value]* ] => multimap - # - # Creates a new multimap populated with the given objects. - # - # Multimap["a", 100, "b", 200] #=> {"a"=>[100], "b"=>[200]} - # Multimap["a" => 100, "b" => 200] #=> {"a"=>[100], "b"=>[200]} - def self.[](*args) - default = [] - - if args.size == 2 && args.last.is_a?(Hash) - default = args.shift - elsif !args.first.is_a?(Hash) && args.size % 2 == 1 - default = args.shift - end - - if args.size == 1 && args.first.is_a?(Hash) - args[0] = args.first.inject({}) { |hash, (key, value)| - unless value.is_a?(default.class) - value = (default.dup << value) - end - hash[key] = value - hash - } - else - index = 0 - args.map! { |value| - unless index % 2 == 0 || value.is_a?(default.class) - value = (default.dup << value) - end - index += 1 - value - } - end - - map = new - map.instance_variable_set(:@hash, Hash[*args]) - map.default = default - map - end - - # call-seq: - # Multimap.new => multimap - # Multimap.new(default) => multimap - # - # Returns a new, empty multimap. - # - # map = Multimap.new(Set.new) - # h["a"] = 100 - # h["b"] = 200 - # h["a"] #=> [100].to_set - # h["c"] #=> [].to_set - def initialize(default = []) - @hash = Hash.new(default) - end - - def initialize_copy(original) #:nodoc: - @hash = Hash.new(original.default.dup) - original._internal_hash.each_pair do |key, container| - @hash[key] = container.dup - end - end - - def_delegators :@hash, :clear, :default, :default=, :empty?, - :fetch, :has_key?, :key? - - # Retrieves the <i>value</i> object corresponding to the - # <i>*keys</i> object. - def [](key) - @hash[key] - end - - # call-seq: - # map[key] = value => value - # map.store(key, value) => value - # - # Associates the value given by <i>value</i> with the key - # given by <i>key</i>. Unlike a regular hash, multiple can be - # assoicated with the same value. - # - # map = Multimap["a" => 100, "b" => 200] - # map["a"] = 9 - # map["c"] = 4 - # map #=> {"a" => [100, 9], "b" => [200], "c" => [4]} - def store(key, value) - update_container(key) do |container| - container << value - container - end - end - alias_method :[]=, :store - - # call-seq: - # map.delete(key, value) => value - # map.delete(key) => value - # - # Deletes and returns a key-value pair from <i>map</i>. If only - # <i>key</i> is given, all the values matching that key will be - # deleted. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.delete("b", 300) #=> 300 - # map.delete("a") #=> [100] - def delete(key, value = nil) - if value - @hash[key].delete(value) - else - @hash.delete(key) - end - end - - # call-seq: - # map.each { |key, value| block } => map - # - # Calls <i>block</i> for each key/value pair in <i>map</i>, passing - # the key and value to the block as a two-element array. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.each { |key, value| puts "#{key} is #{value}" } - # - # <em>produces:</em> - # - # a is 100 - # b is 200 - # b is 300 - def each - each_pair do |key, value| - yield [key, value] - end - end - - # call-seq: - # map.each_association { |key, container| block } => map - # - # Calls <i>block</i> once for each key/container in <i>map</i>, passing - # the key and container to the block as parameters. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.each_association { |key, container| puts "#{key} is #{container}" } - # - # <em>produces:</em> - # - # a is [100] - # b is [200, 300] - def each_association(&block) - @hash.each_pair(&block) - end - - # call-seq: - # map.each_container { |container| block } => map - # - # Calls <i>block</i> for each container in <i>map</i>, passing the - # container as a parameter. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.each_container { |container| puts container } - # - # <em>produces:</em> - # - # [100] - # [200, 300] - def each_container - each_association do |_, container| - yield container - end - end - - # call-seq: - # map.each_key { |key| block } => map - # - # Calls <i>block</i> for each key in <i>hsh</i>, passing the key - # as a parameter. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.each_key { |key| puts key } - # - # <em>produces:</em> - # - # a - # b - # b - def each_key - each_pair do |key, _| - yield key - end - end - - # call-seq: - # map.each_pair { |key_value_array| block } => map - # - # Calls <i>block</i> for each key/value pair in <i>map</i>, - # passing the key and value as parameters. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.each_pair { |key, value| puts "#{key} is #{value}" } - # - # <em>produces:</em> - # - # a is 100 - # b is 200 - # b is 300 - def each_pair - each_association do |key, values| - values.each do |value| - yield key, value - end - end - end - - # call-seq: - # map.each_value { |value| block } => map - # - # Calls <i>block</i> for each key in <i>map</i>, passing the - # value as a parameter. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.each_value { |value| puts value } - # - # <em>produces:</em> - # - # 100 - # 200 - # 300 - def each_value - each_pair do |_, value| - yield value - end - end - - def ==(other) #:nodoc: - case other - when Multimap - @hash == other._internal_hash - else - @hash == other - end - end - - def eql?(other) #:nodoc: - case other - when Multimap - @hash.eql?(other._internal_hash) - else - @hash.eql?(other) - end - end - - def freeze #:nodoc: - each_container { |container| container.freeze } - default.freeze - super - end - - # call-seq: - # map.has_value?(value) => true or false - # map.value?(value) => true or false - # - # Returns <tt>true</tt> if the given value is present for any key - # in <i>map</i>. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.has_value?(300) #=> true - # map.has_value?(999) #=> false - def has_value?(value) - values.include?(value) - end - alias_method :value?, :has_value? - - # call-seq: - # map.index(value) => key - # - # Returns the key for a given value. If not found, returns - # <tt>nil</tt>. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.index(100) #=> "a" - # map.index(200) #=> "b" - # map.index(999) #=> nil - def index(value) - invert[value] - end - - # call-seq: - # map.delete_if {| key, value | block } -> map - # - # Deletes every key-value pair from <i>map</i> for which <i>block</i> - # evaluates to <code>true</code>. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.delete_if {|key, value| value >= 300 } - # #=> Multimap["a" => 100, "b" => 200] - # - def delete_if - each_association do |key, container| - container.delete_if do |value| - yield [key, value] - end - end - self - end - - # call-seq: - # map.reject {| key, value | block } -> map - # - # Same as <code>Multimap#delete_if</code>, but works on (and returns) a - # copy of the <i>map</i>. Equivalent to - # <code><i>map</i>.dup.delete_if</code>. - # - def reject(&block) - dup.delete_if(&block) - end - - # call-seq: - # map.reject! {| key, value | block } -> map or nil - # - # Equivalent to <code>Multimap#delete_if</code>, but returns - # <code>nil</code> if no changes were made. - # - def reject!(&block) - old_size = size - delete_if(&block) - old_size == size ? nil : self - end - - # call-seq: - # map.replace(other_map) => map - # - # Replaces the contents of <i>map</i> with the contents of - # <i>other_map</i>. - # - # map = Multimap["a" => 100, "b" => 200] - # map.replace({ "c" => 300, "d" => 400 }) - # #=> Multimap["c" => 300, "d" => 400] - def replace(other) - case other - when Array - @hash.replace(self.class[self.default, *other]) - when Hash - @hash.replace(self.class[self.default, other]) - when self.class - @hash.replace(other) - else - raise ArgumentError - end - end - - # call-seq: - # map.invert => multimap - # - # Returns a new multimap created by using <i>map</i>'s values as keys, - # and the keys as values. - # - # map = Multimap["n" => 100, "m" => 100, "d" => [200, 300]] - # map.invert #=> Multimap[100 => ["n", "m"], 200 => "d", 300 => "d"] - def invert - h = self.class.new(default.dup) - each_pair { |key, value| h[value] = key } - h - end - - # call-seq: - # map.keys => multiset - # - # Returns a new +Multiset+ populated with the keys from this hash. See also - # <tt>Multimap#values</tt> and <tt>Multimap#containers</tt>. - # - # map = Multimap["a" => 100, "b" => [200, 300], "c" => 400] - # map.keys #=> Multiset.new(["a", "b", "b", "c"]) - def keys - keys = Multiset.new - each_key { |key| keys << key } - keys - end - - # Returns true if the given key is present in Multimap. - def include?(key) - keys.include?(key) - end - alias_method :member?, :include? - - # call-seq: - # map.length => fixnum - # map.size => fixnum - # - # Returns the number of key-value pairs in the map. - # - # map = Multimap["a" => 100, "b" => [200, 300], "c" => 400] - # map.length #=> 4 - # map.delete("a") #=> 100 - # map.length #=> 3 - def size - values.size - end - alias_method :length, :size - - # call-seq: - # map.merge(other_map) => multimap - # - # Returns a new multimap containing the contents of <i>other_map</i> and - # the contents of <i>map</i>. - # - # map1 = Multimap["a" => 100, "b" => 200] - # map2 = Multimap["a" => 254, "c" => 300] - # map2.merge(map2) #=> Multimap["a" => 100, "b" => [200, 254], "c" => 300] - # map1 #=> Multimap["a" => 100, "b" => 200] - def merge(other) - dup.update(other) - end - - # call-seq: - # map.merge!(other_map) => multimap - # map.update(other_map) => multimap - # - # Adds each pair from <i>other_map</i> to <i>map</i>. - # - # map1 = Multimap["a" => 100, "b" => 200] - # map2 = Multimap["b" => 254, "c" => 300] - # - # map1.merge!(map2) - # #=> Multimap["a" => 100, "b" => [200, 254], "c" => 300] - def update(other) - case other - when self.class - other.each_pair { |key, value| store(key, value) } - when Hash - update(self.class[self.default, other]) - else - raise ArgumentError - end - self - end - alias_method :merge!, :update - - # call-seq: - # map.select { |key, value| block } => multimap - # - # Returns a new Multimap consisting of the pairs for which the - # block returns true. - # - # map = Multimap["a" => 100, "b" => 200, "c" => 300] - # map.select { |k,v| k > "a" } #=> Multimap["b" => 200, "c" => 300] - # map.select { |k,v| v < 200 } #=> Multimap["a" => 100] - def select - inject(self.class.new) { |map, (key, value)| - map[key] = value if yield([key, value]) - map - } - end - - # call-seq: - # map.to_a => array - # - # Converts <i>map</i> to a nested array of [<i>key, - # value</i>] arrays. - # - # map = Multimap["a" => 100, "b" => [200, 300], "c" => 400] - # map.to_a #=> [["a", 100], ["b", 200], ["b", 300], ["c", 400]] - def to_a - ary = [] - each_pair do |key, value| - ary << [key, value] - end - ary - end - - # call-seq: - # map.to_hash => hash - # - # Converts <i>map</i> to a basic hash. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.to_hash #=> { "a" => [100], "b" => [200, 300] } - def to_hash - @hash.dup - end - - # call-seq: - # map.containers => array - # - # Returns a new array populated with the containers from <i>map</i>. See - # also <tt>Multimap#keys</tt> and <tt>Multimap#values</tt>. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.containers #=> [[100], [200, 300]] - def containers - containers = [] - each_container { |container| containers << container } - containers - end - - # call-seq: - # map.values => array - # - # Returns a new array populated with the values from <i>map</i>. See - # also <tt>Multimap#keys</tt> and <tt>Multimap#containers</tt>. - # - # map = Multimap["a" => 100, "b" => [200, 300]] - # map.values #=> [100, 200, 300] - def values - values = [] - each_value { |value| values << value } - values - end - - # Return an array containing the values associated with the given keys. - def values_at(*keys) - @hash.values_at(*keys) - end - - def marshal_dump #:nodoc: - @hash - end - - def marshal_load(hash) #:nodoc: - @hash = hash - end - - def to_yaml(opts = {}) #:nodoc: - YAML::quick_emit(self, opts) do |out| - out.map(taguri, to_yaml_style) do |map| - @hash.each do |k, v| - map.add(k, v) - end - map.add('__default__', @hash.default) - end - end - end - - def yaml_initialize(tag, val) #:nodoc: - default = val.delete('__default__') - @hash = val - @hash.default = default - self - end - - protected - def _internal_hash #:nodoc: - @hash - end - - def update_container(key) #:nodoc: - container = @hash[key] - container = container.dup if container.equal?(default) - container = yield(container) - @hash[key] = container - end -end |