Module: Weak::Map::WeakKeysWithDelete

Defined in:
lib/weak/map/weak_keys_with_delete.rb

Overview

This Weak::Map strategy targets Ruby >= 3.3.0. Older Ruby versions require additional indirections implemented in WeakKeys:

Ruby's ObjectSpace::WeakMap uses weak keys and weak values so that either the key or the value can be independently garbage collected. If either of them vanishes, the entry is removed.

The ObjectSpace::WeakMap also allows to delete entries. This allows us to directly use the ObjectSpace::WeakMap as a storage the same way a Set uses a Hash object object as storage.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.usable?Bool

Checks if this strategy is usable for the current Ruby version.

Returns:

  • (Bool)

    truethy for Ruby (aka. MRI, aka. YARV) >= 3.3.0, falsey otherwise



31
32
33
34
# File 'lib/weak/map/weak_keys_with_delete.rb', line 31

def self.usable?
  RUBY_ENGINE == "ruby" &&
    ObjectSpace::WeakMap.instance_methods.include?(:delete)
end

Instance Method Details

#[](key) ⇒ Object

Note:

Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns the value associated with the given key, if found. If key is not found, returns the default value, i.e. the value returned by the default proc (if defined) or the default value (which is initially nil.).

Parameters:

  • key (Object)

    the key for the requested value

Returns:

  • (Object)

    the value associated with the given key, if found. If key is not found, returns the default value, i.e. the value returned by the default proc (if defined) or the default value (which is initially nil.)



37
38
39
40
41
# File 'lib/weak/map/weak_keys_with_delete.rb', line 37

def [](key)
  value = @map[key]
  value = _default(key) if value.nil? && !@map.key?(key)
  value
end

#[]=(key, value) ⇒ Object

Note:

Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Associates the given value with the given key; returns value. If the given key exists, replaces its value with the given value.

Parameters:

  • key (Object)

    the key for the set key-value pair

  • value (Object)

    the value of the set key-value pair

Returns:

  • (Object)

    the given value



44
45
46
47
# File 'lib/weak/map/weak_keys_with_delete.rb', line 44

def []=(key, value)
  @map[key] = value
  value
end

#clearself

Removes all elements and returns self

Returns:

  • (self)


50
51
52
53
# File 'lib/weak/map/weak_keys_with_delete.rb', line 50

def clear
  @map = ObjectSpace::WeakMap.new
  self
end

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

Note:

Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Deletes the key-value pair and returns the value from self whose key is equal to key. If the key is not found, it returns nil. If the optional block is given and the key is not found, pass in the key and return the result of the block.

Parameters:

  • key (Object)

    the key to delete

Yields:

  • (key)

Yield Parameters:

  • key (Object)

    the given key if it was not part of the map

Returns:

  • (Object, nil)

    the value associated with the given key, or the result of the optional block if given the key was not found, or nil if the key was not found and no block was given.



56
57
58
# File 'lib/weak/map/weak_keys_with_delete.rb', line 56

def delete(key, &block)
  @map.delete(key, &block)
end

#each_key {|key| ... } ⇒ self, Enumerator

Calls the given block once for each live key in self, passing the key as a parameter. Returns the weak map itself.

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

Yields:

  • (key)

    calls the given block once for each key in self

Yield Parameters:

  • key (Object)

    the key of the current key-value pair

Returns:

  • (self, Enumerator)

    self if a block was given or an Enumerator if no block was given.



61
62
63
64
65
66
67
68
69
# File 'lib/weak/map/weak_keys_with_delete.rb', line 61

def each_key
  return enum_for(__method__) { size } unless block_given?

  @map.keys.each do |key|
    yield(key)
  end

  self
end

#each_pair {|key, value| ... } ⇒ self, Enumerator

Calls the given block once for each live key in self, passing the key and value as parameters. Returns the weak map itself.

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

Yields:

  • (key, value)

    calls the given block once for each key in self

Yield Parameters:

  • key (Object)

    the key of the current key-value pair

  • value (Object)

    the value of the current key-value pair

Returns:

  • (self, Enumerator)

    self if a block was given or an Enumerator if no block was given.



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/weak/map/weak_keys_with_delete.rb', line 72

def each_pair(&block)
  return enum_for(__method__) { size } unless block_given?

  array = []
  @map.each do |key, value|
    array << key << value
  end
  array.each_slice(2, &block)

  self
end

#each_value {|value| ... } ⇒ self, Enumerator

Calls the given block once for each live key self, passing the live value associated with the key as a parameter. Returns the weak map itself.

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

Yields:

  • (value)

    calls the given block once for each key in self

Yield Parameters:

  • value (Object)

    the value of the current key-value pair

Returns:

  • (self, Enumerator)

    self if a block was given or an Enumerator if no block was given.



85
86
87
88
89
90
91
92
93
# File 'lib/weak/map/weak_keys_with_delete.rb', line 85

def each_value
  return enum_for(__method__) { size } unless block_given?

  @map.values.each do |value|
    yield(value)
  end

  self
end

#fetch(key, default = UNDEFINED) {|key| ... } ⇒ Object

Note:

Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns a value from the hash for the given key. If the key can't be found, there are several options: With no other arguments, it will raise a KeyError exception; if default is given, then that value will be returned; if the optional code block is specified, then it will be called and its result returned.

Parameters:

  • key (Object)

    the key for the requested value

  • default (Object) (defaults to: UNDEFINED)

    a value to return if there is no value at key in the hash

Yields:

  • (key)

    if no value was set at key, no default value was given, and a block was given, we call the block and return its value

Yield Parameters:

  • key (String)

    the given key

Returns:

  • (Object)

    the value for the given key if present in the map. If the key was not found, we return the default value or the value of the given block.

Raises:

  • (KeyError)

    if the key can not be found and no block or default value was provided



96
97
98
99
100
# File 'lib/weak/map/weak_keys_with_delete.rb', line 96

def fetch(key, default = UNDEFINED, &block)
  value = @map[key]
  value = _fetch_default(key, default, &block) if value.nil? && !@map.key?(key)
  value
end

#include?(key) ⇒ Bool

Note:

Set does not test member equality with == or eql?. Instead, it always checks strict object equality, so that, e.g., different strings are not considered equal, even if they may contain the same string content.

Returns true if the given key is included in self and has an associated live value, false otherwise.

Parameters:

  • key (Object)

    a possible key

Returns:

  • (Bool)

    true if the given key is included in self and has an associated live value, false otherwise



103
104
105
# File 'lib/weak/map/weak_keys_with_delete.rb', line 103

def include?(key)
  @map.key?(key)
end

#keysArray

Note:

In contrast to a Hash, Weak::Maps do not necessarily retain insertion order.

Returns an Array containing all keys of the map for which we have a valid value. Keys with garbage-collected values are excluded.

Returns:

  • (Array)

    an Array containing all keys of the map for which we have a valid value. Keys with garbage-collected values are excluded.

See Also:



108
109
110
# File 'lib/weak/map/weak_keys_with_delete.rb', line 108

def keys
  @map.keys
end

#pruneself

Cleanup data structures from the map to remove data associated with deleted or garbage collected keys and/or values. This method may be called automatically for some Weak::Map operations.

Returns:

  • (self)


113
114
115
# File 'lib/weak/map/weak_keys_with_delete.rb', line 113

def prune
  self
end

#sizeInteger

Returns the number of live key-value pairs in self.

Returns:

  • (Integer)

    the number of live key-value pairs in self



118
119
120
# File 'lib/weak/map/weak_keys_with_delete.rb', line 118

def size
  @map.size
end

#valuesArray

Note:

In contrast to a Hash, Weak::Maps do not necessarily retain insertion order.

Returns an Array containing all values of the map for which we have a valid key. Values with garbage-collected keys are excluded.

Returns:

  • (Array)

    an Array containing all values of the map for which we have a valid key. Values with garbage-collected keys are excluded.

See Also:



123
124
125
# File 'lib/weak/map/weak_keys_with_delete.rb', line 123

def values
  @map.values
end