Module: Weak::Map::WeakKeys
- Defined in:
- lib/weak/map/weak_keys.rb
Overview
This Weak::Map strategy targets Ruby < 3.3.0.
Its 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
does not allow to explicitly delete entries.
We emulate this by setting the garbage-collectible value of a deleted
entry to a simple new object. This value will be garbage collected on the
next GC run which will then remove the entry. When accessing elements, we
delete and filter out these recently deleted entries.
Class Method Summary collapse
-
.usable? ⇒ Bool
Checks if this strategy is usable for the current Ruby version.
Instance Method Summary collapse
-
#[](key) ⇒ Object
The value associated with the given
key
, if found. -
#[]=(key, value) ⇒ Object
Associates the given
value
with the givenkey
; returnsvalue
. -
#clear ⇒ self
Removes all elements and returns
self
. -
#delete(key) {|key| ... } ⇒ Object?
Deletes the key-value pair and returns the value from
self
whose key is equal tokey
. -
#each_key {|key| ... } ⇒ self, Enumerator
Calls the given block once for each live key in
self
, passing the key as a parameter. -
#each_pair {|key, value| ... } ⇒ self, Enumerator
Calls the given block once for each live key in
self
, passing the key and value as parameters. -
#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. -
#fetch(key, default = UNDEFINED) {|key| ... } ⇒ Object
Returns a value from the hash for the given
key
. -
#include?(key) ⇒ Bool
true
if the given key is included inself
and has an associated live value,false
otherwise. -
#keys ⇒ Array
An
Array
containing all keys of the map for which we have a valid value. -
#prune ⇒ self
Cleanup data structures from the map to remove data associated with deleted or garbage collected keys and/or values.
-
#size ⇒ Integer
The number of live key-value pairs in
self
. -
#values ⇒ Array
An
Array
containing all values of the map for which we have a valid key.
Class Method Details
.usable? ⇒ Bool
Checks if this strategy is usable for the current Ruby version.
30 31 32 |
# File 'lib/weak/map/weak_keys.rb', line 30 def self.usable? RUBY_ENGINE == "ruby" end |
Instance Method Details
#[](key) ⇒ Object
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
.).
35 36 37 38 |
# File 'lib/weak/map/weak_keys.rb', line 35 def [](key) raw_value = @map[key] missing?(raw_value) ? _default(key) : value!(raw_value) end |
#[]=(key, value) ⇒ Object
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
.
41 42 43 44 |
# File 'lib/weak/map/weak_keys.rb', line 41 def []=(key, value) @map[key] = value.nil? ? NIL : value value end |
#clear ⇒ self
Removes all elements and returns self
47 48 49 50 |
# File 'lib/weak/map/weak_keys.rb', line 47 def clear @map = ObjectSpace::WeakMap.new self end |
#delete(key) {|key| ... } ⇒ Object?
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.
53 54 55 56 57 58 59 60 61 |
# File 'lib/weak/map/weak_keys.rb', line 53 def delete(key) raw_value = @map[key] if have?(raw_value) @map[key] = DeletedEntry.new value!(raw_value) elsif block_given? yield(key) end 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.
64 65 66 67 68 69 70 71 |
# File 'lib/weak/map/weak_keys.rb', line 64 def each_key return enum_for(__method__) { size } unless block_given? @map.keys.each do |key| yield key unless missing?(@map[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.
74 75 76 77 78 79 80 81 82 |
# File 'lib/weak/map/weak_keys.rb', line 74 def each_pair return enum_for(__method__) { size } unless block_given? @map.keys.each do |key| raw_value = @map[key] yield [key, value!(raw_value)] unless missing?(raw_value) end 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.
85 86 87 88 89 90 91 92 |
# File 'lib/weak/map/weak_keys.rb', line 85 def each_value return enum_for(__method__) { size } unless block_given? @map.values.each do |raw_value| yield value!(raw_value) unless missing?(raw_value) end self end |
#fetch(key, default = UNDEFINED) {|key| ... } ⇒ Object
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.
95 96 97 98 99 100 101 102 |
# File 'lib/weak/map/weak_keys.rb', line 95 def fetch(key, default = UNDEFINED, &block) raw_value = @map[key] if have?(raw_value) value!(raw_value) else _fetch_default(key, default, &block) end end |
#include?(key) ⇒ Bool
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.
105 106 107 |
# File 'lib/weak/map/weak_keys.rb', line 105 def include?(key) have?(@map[key]) end |
#keys ⇒ Array
In contrast to a Hash
, Weak::Map
s 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.
110 111 112 |
# File 'lib/weak/map/weak_keys.rb', line 110 def keys @map.keys.delete_if { |key| missing?(@map[key]) } end |
#prune ⇒ self
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.
115 116 117 |
# File 'lib/weak/map/weak_keys.rb', line 115 def prune self end |
#size ⇒ Integer
Returns the number of live key-value pairs in self
.
120 121 122 |
# File 'lib/weak/map/weak_keys.rb', line 120 def size each_key.count end |
#values ⇒ Array
In contrast to a Hash
, Weak::Map
s 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.
125 126 127 128 129 130 131 |
# File 'lib/weak/map/weak_keys.rb', line 125 def values values = [] @map.values.each do |raw_value| values << value!(raw_value) unless missing?(raw_value) end values end |