Class: MapWithIndifferentAccess::Map

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
WrapsCollection
Defined in:
lib/map_with_indifferent_access/map.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(basis = {}) ⇒ Map

Initializes a new MapWithIndifferentAccess::Map that encapsulates a new empty Array or the Array coerced from the given basis.

When a MapWithIndifferentAccess::Map is given as a basis, this results on the given and new instances sharing the same #inner_map. There is no obvious reason to do that on purpose, but there is also no likely harm in allowing it to happen.

Parameters:

Raises:

  • (ArgumentError)

82
83
84
85
86
87
88
# File 'lib/map_with_indifferent_access/map.rb', line 82

def initialize(basis={})
  use_basis = basis
  use_basis = basis.inner_map if self.class === basis
  use_basis = Hash.try_convert( use_basis )
  raise ArgumentError, "Could not convert #{basis.inspect} into a Hash" unless use_basis
  @inner_map = use_basis
end

Instance Attribute Details

#inner_collectionObject (readonly) Originally defined in module WrapsCollection

The encapsulated collection object.

Raises:

  • (NotImplementedError)

#inner_mapObject (readonly) Also known as: inner_collection

The encapsuated Hash object.


42
43
44
# File 'lib/map_with_indifferent_access/map.rb', line 42

def inner_map
  @inner_map
end

Class Method Details

.try_convert(from_obj) ⇒ Map?

Try to convert from_obj into a MapWithIndifferentAccess::Map.

Returns:

  • (Map)

    converted object if from_obj is convertible.

  • (nil)

    if from_obj cannot be converted for any reason.


14
15
16
17
18
19
20
21
# File 'lib/map_with_indifferent_access/map.rb', line 14

def self.try_convert(from_obj)
  if self === from_obj
    from_obj
  else
    hash = Hash.try_convert( from_obj )
    new( hash ) if hash
  end
end

.try_deconstruct(obj) ⇒ Hash?

Try to convert obj, which might be a MapWithIndifferentAccess::Map into a Hash.

Returns:

  • (Hash)

    converted object if obj is convertible.

  • (nil)

    if obj cannot be converted for any reason.


30
31
32
33
34
35
36
37
38
39
# File 'lib/map_with_indifferent_access/map.rb', line 30

def self.try_deconstruct(obj)
  if self === obj
    obj.inner_map
  elsif obj.respond_to?(:to_hash )
    h = obj.to_hash
    Hash === h ? h : nil
  else
    nil
  end
end

Instance Method Details

#==(other) ⇒ Boolean

Returns true if the entries in other (a MapWithIndifferentAccess::Map, Hash, or other Hash-like object) are equal in numer and equivalent to the entries in the target MapWithIndifferentAccess::Map.

Entries are equivalent if their keys are equivalent with String/Symbolic indifference and their externalized values are equal using ==.

Returns:

  • (Boolean)

303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/map_with_indifferent_access/map.rb', line 303

def ==(other)
  return true if equal?( other )
  other = self.class.try_convert( other )
  return false unless other

  return true if inner_map == other.inner_map
  return false if length != other.length
  each do |(key, value)|
    other_val = other.fetch(key) { return false }
    return false unless value == other_val
  end

  true
end

#[](key) ⇒ Object

Returns the externalization of the value from the target's #inner_map entry having a key that conforms to the given key if applicable.

When there is no entry with a conforming key, returns the externalization of the #inner_map Hash's default value for the given key (normally nil).


171
172
173
174
175
# File 'lib/map_with_indifferent_access/map.rb', line 171

def[](key)
  key = conform_key( key )
  value = inner_map[ key ]
  Values >> value
end

#[]=(key, value) ⇒ Object Also known as: store

Creates an entry or replaces the value of an existing entry in the target's #inner_map Hash.

When the key conforms to a key in the target map, then the value of the matching entry in the target's #inner_map is replaced with the internalization of value.

When key does not conform to a key in the target map, then a new entry is added using the given key and the internalization of value.

Returns the given value.


152
153
154
155
156
157
# File 'lib/map_with_indifferent_access/map.rb', line 152

def[]=(key, value)
  key = conform_key( key )
  intern_value = Values << value
  inner_map[ key ] = intern_value
  value
end

#_frozen?Boolean Originally defined in module WrapsCollection

Returns true when the target object (the wrapper) is frozen.

There are some cases in which this returns false when #frozen? would return true.

Returns:

  • (Boolean)

See Also:

#any? {|pair| ... } ⇒ Boolean #any?Boolean

Iterates over entries in the target MapWithIndifferentAccess::Map, passing a [ key, externalized_value ] Array to the block for each of those, and returns true when the block returns true for any entry.

Overloads:

  • #any? {|pair| ... } ⇒ Boolean

    Yield Parameters:

    • pair (Array<(Object, Object)>)

      [ key, externalized_value ]

  • #any?Boolean

    Due to the behavior of Enumerable::any? when no block is given, this is effectively synonymous with !target_map.empty?.

Returns:

  • (Boolean)

See Also:


# File 'lib/map_with_indifferent_access/map.rb', line 116

#assoc(obj) ⇒ Array?

Searches through the map, comparing the conformation of obj with each entry's key using ==. Returns a 2-element array containing the key and externalized value from the matching element or returns or nil if no match is found.

Returns:

  • (Array, nil)

See Also:


577
578
579
580
581
582
583
584
585
# File 'lib/map_with_indifferent_access/map.rb', line 577

def assoc(obj)
  obj = conform_key( obj )
  entry = inner_map.assoc( obj )
  unless entry.nil?
    value = Values >> entry[ 1 ]
    entry[ 1 ] = value
  end
  entry
end

#clearObject Originally defined in module WrapsCollection

Removes all entries from the target's #inner_collection.

#conform_key(given_key) ⇒ Object

Returns the given_key object if it is a key in the target's #inner_map Hash or if neither given_key nor its String/Symbol alternative is a key in the #inner_map.

When given_key is a String that is not a key in the target's #inner_map, returns the symbolization of given_key if that symbolization is a key in the #inner_map.

When given_key is a Symbol that is not a key in the target's #inner_map, returns the stringification of given_key if that stringification is a key in the #inner_map.


103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/map_with_indifferent_access/map.rb', line 103

def conform_key(given_key)
  case given_key
  when String
    alt_key = inner_map.key?( given_key ) ? given_key : given_key.to_sym
    inner_map.key?( alt_key ) ? alt_key : given_key
  when Symbol
    alt_key = inner_map.key?( given_key ) ? given_key : "#{given_key}"
    inner_map.key?( alt_key ) ? alt_key : given_key
  else
    given_key
  end
end

#default(key = nil) ⇒ Object

Returns the default value, the value that would be returned by <target>[key] if the conformation of key did not exist in the target.

See Also:


239
240
241
242
# File 'lib/map_with_indifferent_access/map.rb', line 239

def default(key = nil)
  inner_default = inner_map.default( key )
  Values >> inner_default
end

#default=(obj) ⇒ Object

Sets the default value returned from the target's #inner_map Hash for a key that does not exist to be the internlization of obj.


230
231
232
# File 'lib/map_with_indifferent_access/map.rb', line 230

def default=(obj)
  inner_map.default = Values << obj
end

#default_procProc?

If the target MapWithIndifferentAccess::Map's #inner_map Hash does not have a default proc assigned, then this returns nil.

If Proc has been previously assigned to the target MapWithIndifferentAccess::Map using #default_proc= and is is still applicable, then that Proc is returned.

If no Proc was assigned to the target MapWithIndifferentAccess::Map or that assignment is no longer applicable, but the #inner_map Hash has a default proc, then a wrapper around that Proc is returned that accepts a Map or Hash-like object and a key, passing the Map-deconstruction of the Map/Hash and the unmodified key value to the underlying Proc, finally returning the externalization of the value returned from the call to the underlying Proc.

Returns:

  • (Proc, nil)

281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/map_with_indifferent_access/map.rb', line 281

def default_proc
  return nil unless inner_map.default_proc
  unless inner_map.default_proc.equal?( _inner_proc_for_default_proc )
    self._default_proc = nil
  end
  return _default_proc if _default_proc
  _default_proc = ->(map,key){
    hash = self.class.try_deconstruct( map )
    value = inner_map.default_proc.call( hash, key )
    Values >> value
  }
end

#default_proc=(proc_obj) ⇒ Object

Sets the #inner_map Hash's default proc to a wrapper around proc_obj that passes the target MapWithIndifferentAccess::Map and the key as parameters and returns the internalization of the wrapped proc's block.

When running in Ruby 2.x or newer, the default proc can also be cleared by passing nil for proc_obj.

Parameters:

  • proc_obj (Proc, nil)

See Also:

  • Hash#default_proc=

254
255
256
257
258
259
260
261
262
# File 'lib/map_with_indifferent_access/map.rb', line 254

def default_proc=(proc_obj)
  inner_proc = ->(_, key){
    Values << proc_obj.call( self, key )
  }
  inner_map.default_proc = inner_proc
  self._default_proc = proc_obj
  self._inner_proc_for_default_proc = inner_proc
  proc_obj
end

#delete(key) ⇒ Object #delete(key) {|key| ... } ⇒ Object

Delete the externalization of the value associated with the conformation of the given key or default value.

Overloads:

  • #delete(key) ⇒ Object

    Returns the externalization of the value returned from the #inner_map Hash on deletion.

  • #delete(key) {|key| ... } ⇒ Object

    Returns the externalization of the value returned by the given block for the given key.

    Yield Parameters:

    • key

See Also:


398
399
400
401
402
403
404
405
406
# File 'lib/map_with_indifferent_access/map.rb', line 398

def delete(key)
  key = conform_key( key )
  value = if block_given?
    inner_map.delete( key ) { |key| yield key }
  else
    inner_map.delete( key )
  end
  Values >> value
end

#delete_if {|key, value| ... } ⇒ Map #delete_ifEnumerator

Deletes every entry for which the block evaluates to true given the entry's key and externalized value.

If no block is given, then an Enumerator is returned instead.

Overloads:

  • #delete_if {|key, value| ... } ⇒ Map

    Yield Parameters:

    • key
    • value

    Returns:

  • #delete_ifEnumerator

    Returns:

    • (Enumerator)

See Also:


471
472
473
474
475
476
477
478
479
480
# File 'lib/map_with_indifferent_access/map.rb', line 471

def delete_if
  return enum_for(:delete_if ) unless block_given?

  inner_map.delete_if do |key, value|
    value = Values >> value
    yield key, value
  end

  self
end

#each {|key, value| ... } ⇒ MapWithIndifferentAccess::Map #eachEnumerator Also known as: each_pair

When a block argument is given, calls the block once for each of the target's entries, passing the entry's key and externalized value as parameters, and then returns the target object.

When no block argument is given, returns an Enumerator.

Overloads:


332
333
334
335
336
337
338
339
340
# File 'lib/map_with_indifferent_access/map.rb', line 332

def each
  return enum_for(:each ) unless block_given?

  each_key do |key|
    value = fetch( key )
    value = Values >> value
    yield [key, value]
  end
end

#each_keyMapWithIndifferentAccess::Map

When a block argument is given, calls the block once for each of the target's keys, passing the key as a parameter, and then returns the target object.

When no block argument is given, returns an Enumerator.


351
352
353
354
355
356
357
# File 'lib/map_with_indifferent_access/map.rb', line 351

def each_key
  return enum_for(:each_key ) unless block_given?
  inner_map.each_key do |key|
    yield key
  end
  self
end

#each_valueMapWithIndifferentAccess::Map

When a block argument is given, calls the block once for each of the target's entries, passing externalization the entry value as a parameter, and then returns the target.

When no block argument is given, returns an Enumerator.


366
367
368
369
370
371
372
373
374
# File 'lib/map_with_indifferent_access/map.rb', line 366

def each_value
  return enum_for(:each_value) unless block_given?

  inner_map.each_value do |value|
    value = Values >> value
    yield value
  end
  self
end

#empty?Boolean Originally defined in module WrapsCollection

Returns true if the collection contains no entries.

Returns false if the collection contains 1 or more entries.

Returns:

  • (Boolean)

#eql?(other) ⇒ Boolean Originally defined in module WrapsCollection

Returns true for another instance of the same class as the target where the target's #inner_collection is #eql? to the given object's #inner_collection. Returns false otherwise.

Returns:

  • (Boolean)

#fetch(key, *more_args) ⇒ Object


177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/map_with_indifferent_access/map.rb', line 177

def fetch(key, *more_args)
  expect_arity 1..2, key, *more_args
  if block_given? && !more_args.empty?
    warn "#{caller[ 0 ]}: warning: block supersedes default value argument"
  end

  conformed_key = conform_key( key )

  value = if inner_map.key?( conformed_key )
    inner_map.fetch( conformed_key )
  elsif block_given?
    inner_map.fetch( key ) {|key| yield key }
  else
    inner_map.fetch( key, *more_args )
  end

  Values >> value
end

#freezeObject Originally defined in module WrapsCollection

Freezes both the target map and its #inner_collection object.

#frozen?Boolean Originally defined in module WrapsCollection

Reflects the frozen-ness of its #inner_collection.

Returns true when the #inner_collection is frozen ( and the target/wrapper might be frozen or not).

Returns false when the #inner_collection is not frozen (and neither is the target/wrapper).

When the #inner_collection is frozen, but the target object is not, then the target behaves as if frozen in most ways, but some of the restrictions that Ruby applies to truly frozen (such as preventing instance methods from being dynamically added to the object) do not apply.

Returns:

  • (Boolean)

See Also:

#has_value?(value) ⇒ Boolean

Returns true if the internalization of value is present for some key in the target.

Returns:

  • (Boolean)

See Also:


593
594
595
596
# File 'lib/map_with_indifferent_access/map.rb', line 593

def has_value?(value)
  value = Values >> value
  each_value.any? { |v| v == value }
end

#hashFixnum Originally defined in module WrapsCollection

Compute a hash-code for this collection wrapper. Two wrappers with the same type and the same #inner_collection content will have the same hash code (and will match using #eql?).

Returns:

  • (Fixnum)

#invertMap

Returns a new MapWithIndifferentAccess::Map with an #inner_map Hash created by using the the target's #inner_map's values as keys and keys as values.

Returns:


740
741
742
# File 'lib/map_with_indifferent_access/map.rb', line 740

def invert
  self.class.new( inner_map.invert )
end

#keep_if {|key, value| ... } ⇒ Map #keep_ifEnumerator

Deletes every entry for which the block evaluates to false, given the entry's key and externalized value.

If no block is given, then an Enumerator is returned instead.

Overloads:

  • #keep_if {|key, value| ... } ⇒ Map

    Yield Parameters:

    • key
    • value

    Returns:

  • #keep_ifEnumerator

    Returns:

    • (Enumerator)

See Also:


545
546
547
548
549
550
551
552
553
554
# File 'lib/map_with_indifferent_access/map.rb', line 545

def keep_if
  return enum_for(:keep_if ) unless block_given?

  inner_map.keep_if do |key, value|
    value = Values >> value
    yield key, value
  end

  self
end

#key(value) ⇒ Object?

Returns the key for an entry, the externalization of which is equal to the externalization of value. Returns nil if no match is found.

Returns:

  • (Object, nil)

See Also:


222
223
224
225
# File 'lib/map_with_indifferent_access/map.rb', line 222

def key(value)
  entry = rassoc( value )
  entry ? entry.first : nil
end

#key?(key) ⇒ Boolean Also known as: has_key?, include?, member?

Returns true if the conformation of key is present in the target MapWithIndifferentAccess::Map.

Returns:

  • (Boolean)

200
201
202
203
204
205
206
207
208
209
# File 'lib/map_with_indifferent_access/map.rb', line 200

def key?(key)
  case key
  when String
    inner_map.key?( key ) || inner_map.key?( key.to_sym )
  when Symbol
    inner_map.key?( key ) || inner_map.key?("#{key}")
  else
    inner_map.key?( key )
  end
end

#keysArray

Returns a new Array populated with the keys from this MapWithIndifferentAccess::Map.

Returns:

  • (Array)

See Also:


# File 'lib/map_with_indifferent_access/map.rb', line 45

#lengthFixnum Originally defined in module WrapsCollection

The number of entries in the collection.

Returns:

  • (Fixnum)

See Also:

#merge(other) ⇒ Map #merge(other) {|key, oldval, newval| ... } ⇒ Map

Returns a new MapWithIndifferentAccess::Map containing the contents of other (a MapWithIndifferentAccess::Map, Hash, or other Hash-like object) and of the target MapWithIndifferentAccess::Map.

Each entry in other with key that is equivalent to a key in the target (with String/Symbol indifference) is treated as a collision.

Overloads:

  • #merge(other) ⇒ Map

    Each collision produces an entry with its key from the entry in target and its value from the entry in other.

  • #merge(other) {|key, oldval, newval| ... } ⇒ Map

    Each collision produces an entry with its key from the target-side entry and its value from the internalization of the block call result.

    Yield Parameters:

    • key

      The key from the target-side colliding entry.

    • oldval

      The externalization of value from the target-side colliding entry.

    • newval

      The externalization of value from the other-side colliding entry.

Returns:

See Also:


656
657
658
659
660
661
662
# File 'lib/map_with_indifferent_access/map.rb', line 656

def merge(other)
  if block_given?
    dup.merge!( other ){ |*args| yield *args }
  else
    dup.merge!( other )
  end
end

#merge!(other) ⇒ Map #merge!(other) {|key, oldval, newval| ... } ⇒ Map Also known as: update

Adds the contents of other (a MapWithIndifferentAccess::Map, Hash, or other Hash-like object) to the target MapWithIndifferentAccess::Map.

Each entry in other with key that is equivalent to a key in the target (with String/Symbol indifference) is treated as a collision.

Overloads:

  • #merge!(other) ⇒ Map

    Each collision produces an entry with its key from the entry in target and its value from the entry in other.

  • #merge!(other) {|key, oldval, newval| ... } ⇒ Map

    Each collision produces an entry with its key from the target-side entry and its value from the internalization of the block call result.

    Yield Parameters:

    • key

      The key from the target-side colliding entry.

    • oldval

      The externalization of value from the target-side colliding entry.

    • newval

      The externalization of value from the other-side colliding entry.

Returns:

See Also:


697
698
699
700
701
702
703
704
705
706
707
# File 'lib/map_with_indifferent_access/map.rb', line 697

def merge!(other)
  other.each_pair do |(key, value)|
    key = conform_key( key )
    if block_given? && inner_map.key?(key)
      self[key] = yield( key, self[key], value )
    else
      self[key] = value
    end
  end
  self
end

#rassoc(value) ⇒ Array?

Searches through the map, comparing the externalization of value with the externalized value of each entry using ==. Returns a 2-element array containing the key and externalized value from the matching element or returns or nil if no match is found.

Returns:

  • (Array, nil)

See Also:


608
609
610
611
612
613
614
615
616
617
618
619
620
# File 'lib/map_with_indifferent_access/map.rb', line 608

def rassoc(value)
  value = Values >> value
  entry = inner_map.detect { |(k, v)|
    v = Values >> v
    value == v
  }
  if entry
    entry[ 1 ] = Values >> entry[ 1 ]
    entry
  else
    nil
  end
end

#rehashMap

Rebuilds the target's #inner_map Hash based on the current #hash values for each key. If values of key objects have changed since they were inserted, this will re-index that Hash.

If #rehash is called while an iterator is traversing the MapWithIndifferentAccess::Map or its #inner_map Hash, a RuntimeError will be raised in the iterator.

Returns:


64
65
66
67
68
# File 'lib/map_with_indifferent_access/map.rb', line 64

def_delegators(
  :inner_map,
  :keys,
  :rehash,
)

#reject {|key| ... } ⇒ Map #rejectEnumerator

Returns a new MapWithIndifferentAccess::Map consisting of entries for which the block returns false, given the entry's key and externalized value.

If no block is given, then an Enumerator is returned instead.

Overloads:

  • #reject {|key| ... } ⇒ Map

    Yield Parameters:

    • key

    Returns:

  • #rejectEnumerator

    Returns:

    • (Enumerator)

See Also:


423
424
425
426
427
428
429
# File 'lib/map_with_indifferent_access/map.rb', line 423

def reject
  return enum_for(:reject ) unless block_given?

  dup.delete_if{ |key, value|
    yield( key, value )
  }
end

#reject! {|key, value| ... } ⇒ Map? #reject!Enumerator

Equivalent to #delete_if, but returns nil if no changes were made.

Overloads:

  • #reject! {|key, value| ... } ⇒ Map?

    Yield Parameters:

    • key
    • value

    Returns:

  • #reject!Enumerator

    Returns:

    • (Enumerator)

See Also:


443
444
445
446
447
448
449
450
451
452
453
454
# File 'lib/map_with_indifferent_access/map.rb', line 443

def reject!
  return enum_for(:reject!) unless block_given?

  has_rejections = false
  delete_if{ |key, value|
    is_rejected = yield( key, value )
    has_rejections ||= is_rejected
    is_rejected
  }

  has_rejections ? self : nil
end

#replace(other) ⇒ Map

Replace the contents of the target's #inner_map Hash with the deconstruction of the given Hash-like object.

Returns:

See Also:


562
563
564
565
566
# File 'lib/map_with_indifferent_access/map.rb', line 562

def replace(other)
  other_d = self.class.try_deconstruct( other ) || other
  inner_map.replace other_d
  return self
end

#select {|key| ... } ⇒ Map #selectEnumerator

Returns a new MapWithIndifferentAccess::Map consisting of entries for which the block returns true, given the entry's key and externalized value.

If no block is given, then an Enumerator is returned instead.

Overloads:

  • #select {|key| ... } ⇒ Map

    Yield Parameters:

    • key

    Returns:

  • #selectEnumerator

    Returns:

    • (Enumerator)

See Also:


497
498
499
500
501
502
503
# File 'lib/map_with_indifferent_access/map.rb', line 497

def select
  return enum_for(:select ) unless block_given?

  dup.keep_if{ |key, value|
    yield( key, value )
  }
end

#select! {|key, value| ... } ⇒ Map? #select!Enumerator

Equivalent to #keep_if, but returns nil if no changes were made.

Overloads:

  • #select! {|key, value| ... } ⇒ Map?

    Yield Parameters:

    • key
    • value

    Returns:

  • #select!Enumerator

    Returns:

    • (Enumerator)

See Also:


517
518
519
520
521
522
523
524
525
526
527
528
# File 'lib/map_with_indifferent_access/map.rb', line 517

def select!
  return enum_for(:select!) unless block_given?

  has_rejections = false
  keep_if{ |key, value|
    is_selected = yield( key, value )
    has_rejections ||= ! is_selected
    is_selected
  }

  has_rejections ? self : nil
end

#shiftArray, Object

Removes an entry from the target MapWithIndifferentAccess::Map and returns a 2-item Array [ <key>, <externalized value> ] or the externalization of the MapWithIndifferentAccess::Map's default value if it is empty.

Yes, the behavior when the behavior for an empty MapWithIndifferentAccess::Map with a non-nil default is weird and troublesome, but it is parallel to the similarly weird behavior of Hash#shift.

Returns:

  • (Array, Object)

See Also:


723
724
725
726
727
728
729
730
731
732
733
# File 'lib/map_with_indifferent_access/map.rb', line 723

def shift
  if inner_map.empty?
    Values >> inner_map.shift
  else
    inner_result = inner_map.shift
    [
      inner_result[ 0 ],
      Values >> inner_result[ 1 ]
    ]
  end
end

#sizeFixnum Originally defined in module WrapsCollection

The number of entries in the collection.

Returns:

  • (Fixnum)

See Also:

#taintObject Originally defined in module WrapsCollection

Causes the target's #inner_collection to be tainted.

#tainted?Boolean Originally defined in module WrapsCollection

Reflects the tainted-ness of its #inner_collection.

Returns:

  • (Boolean)

#trustObject Originally defined in module WrapsCollection

Causes the target's #inner_collection to be trusted.

#untaintObject Originally defined in module WrapsCollection

Causes the target's #inner_collection to be untainted.

#untrustObject Originally defined in module WrapsCollection

Causes the target's #inner_collection to be untrusted.

#untrusted?Boolean Originally defined in module WrapsCollection

Reflects the untrusted-ness of its #inner_collection.

Returns:

  • (Boolean)

#valuesList

Returns a List containing the entry values from the target MapWithIndifferentAccess::Map.

Returns:


379
380
381
# File 'lib/map_with_indifferent_access/map.rb', line 379

def values
  List.new( inner_map.values )
end