class ObjectSpace::WeakKeyMap

Parent:
Object

An ObjectSpace::WeakKeyMap is a key-value map that holds weak references to its keys, so they can be garbage collected when there is no more references.

Unlike ObjectSpace::WeakMap:

  • references to values are strong, so they aren’t garbage collected while they are in the map;

  • keys are compared by value (using Object#eql?), not by identity;

  • only garbage-collectable objects can be used as keys.

    map = ObjectSpace::WeakKeyMap.new
    val = Time.new(2023, 12, 7)
    key = "name"
    map[key] = val
    
    # Value is fetched by equality: the instance of string "name" is
    # different here, but it is equal to the key
    map["name"] #=> 2023-12-07 00:00:00 +0200
    
    val = nil
    GC.start
    # There are no more references to `val`, yet the pair isn't
    # garbage-collected.
    map["name"] #=> 2023-12-07 00:00:00 +0200
    
    key = nil
    GC.start
    # There are no more references to `key`, key and value are
    # garbage-collected.
    map["name"] #=> nil
    

(Note that GC.start is used here only for demonstrational purposes and might not always lead to demonstrated results.)

The collection is especially useful for implementing caches of lightweight value objects, so that only one copy of each value representation would be stored in memory, but the copies that aren’t used would be garbage-collected.

CACHE = ObjectSpace::WeakKeyMap

def make_value(**)
   val = ValueObject.new(**)
   if (existing = @cache.getkey(val))
      # if the object with this value exists, we return it
      existing
   else
      # otherwise, put it in the cache
      @cache[val] = true
      val
   end
end

This will result in make_value returning the same object for same set of attributes always, but the values that aren’t needed anymore wouldn’t be sitting in the cache forever.

Ruby Core © 1993–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.