Class: NestedMultimap

Inherits:
Multimap show all
Defined in:
lib/rack/mount/vendor/multimap/nested_multimap.rb

Overview

NestedMultimap allows values to be assoicated with a nested set of keys.

Direct Known Subclasses

Rack::Mount::Multimap

Instance Method Summary collapse

Methods inherited from Multimap

#==, [], #containers, #delete, #delete_if, #each, #each_container, #each_key, #each_pair, #each_value, #eql?, #freeze, #has_value?, #include?, #index, #initialize, #initialize_copy, #invert, #keys, #marshal_dump, #marshal_load, #merge, #reject, #reject!, #replace, #select, #size, #to_a, #to_hash, #to_yaml, #update, #values, #values_at, #yaml_initialize

Constructor Details

This class inherits a constructor from Multimap

Instance Method Details

#<<(value) ⇒ Object

call-seq:

multimap << obj  => multimap

Pushes the given object on to the end of all the containers.

map = NestedMultimap["a" => [100], "b" => [200, 300]]
map << 300
map["a"] #=> [100, 300]
map["c"] #=> [300]


47
48
49
50
51
# File 'lib/rack/mount/vendor/multimap/nested_multimap.rb', line 47

def <<(value)
  @hash.each_value { |container| container << value }
  self.default << value
  self
end

#[](*keys) ⇒ Object

call-seq:

multimap[*keys]               =>  value
multimap[key1, key2, key3]    =>  value

Retrieves the value object corresponding to the *keys object.



59
60
61
62
63
64
65
66
# File 'lib/rack/mount/vendor/multimap/nested_multimap.rb', line 59

def [](*keys)
  i, l, r, k = 0, keys.length, self, self.class
  while r.is_a?(k)
    r = i < l ? r._internal_hash[keys[i]] : r.default
    i += 1
  end
  r
end

#containers_with_defaultObject

call-seq:

multimap.containers_with_default    => array

Returns a new array populated with all the containers from map including the default.

map = NestedMultimap.new
map["a"] = 100
map["a", "b"] = 101
map["a"] = 102
map.containers_with_default   #=> [[100, 101, 102], [100, 102], []]


133
134
135
136
137
# File 'lib/rack/mount/vendor/multimap/nested_multimap.rb', line 133

def containers_with_default
  containers = []
  each_container_with_default { |container| containers << container }
  containers
end

#each_associationObject

call-seq:

multimap.each_association { |key, container| block } => multimap

Calls block once for each key/container in map, passing the key and container to the block as parameters.

map = NestedMultimap.new
map["a"] = 100
map["a", "b"] = 101
map["a"] = 102
map["c"] = 200
map.each_association { |key, container| puts "#{key} is #{container}" }

produces:

["a", "b"] is [100, 101, 102]
"c" is [200]


85
86
87
88
89
90
91
92
93
94
95
# File 'lib/rack/mount/vendor/multimap/nested_multimap.rb', line 85

def each_association
  super() do |key, container|
    if container.respond_to?(:each_association)
      container.each_association do |nested_key, value|
        yield [key, nested_key].flatten, value
      end
    else
      yield key, container
    end
  end
end

#each_container_with_default(&block) ⇒ Object

call-seq:

multimap.each_container_with_default { |container| block } => map

Calls block for every container in map including the default, passing the container as a parameter.

map = NestedMultimap.new
map["a"] = 100
map["a", "b"] = 101
map["a"] = 102
map.each_container_with_default { |container| puts container }

produces:

[100, 101, 102]
[100, 102]
[]


114
115
116
117
118
119
120
# File 'lib/rack/mount/vendor/multimap/nested_multimap.rb', line 114

def each_container_with_default(&block)
  @hash.each_value do |container|
    iterate_over_container(container, &block)
  end
  iterate_over_container(default, &block)
  self
end

#inspectObject

:nodoc:



139
140
141
# File 'lib/rack/mount/vendor/multimap/nested_multimap.rb', line 139

def inspect #:nodoc:
  super.gsub(/\}$/, ", default => #{default.inspect}}")
end

#store(*args) ⇒ Object Also known as: []=

call-seq:

multimap[*keys] = value      => value
multimap.store(*keys, value) => value

Associates the value given by value with multiple key given by keys.

map = NestedMultimap.new
map["a"] = 100
map["a", "b"] = 101
map["a"] = 102
map   #=> {"a"=>{"b"=>[100, 101, 102], default => [100, 102]}}

Raises:

  • (ArgumentError)


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rack/mount/vendor/multimap/nested_multimap.rb', line 18

def store(*args)
  keys  = args
  value = args.pop

  raise ArgumentError, 'wrong number of arguments (1 for 2)' unless value

  if keys.length > 1
    update_container(keys.shift) do |container|
      container = self.class.new(container) unless container.is_a?(self.class)
      container[*keys] = value
      container
    end
  elsif keys.length == 1
    super(keys.first, value)
  else
    self << value
  end
end