class ObjectSpace::WeakMap
An ObjectSpace::WeakMap
is a key-value map that holds weak references to its keys and values, so they can be garbage-collected when there are no more references left.
Keys in the map are compared by identity.
m = ObjectSpace::WeakMap.new key1 = "foo" val1 = Object.new m[key1] = val1 key2 = "bar" val2 = Object.new m[key2] = val2 m[key1] #=> #<Object:0x0...> m[key2] #=> #<Object:0x0...> val1 = nil # remove the other reference to value GC.start m[key1] #=> nil m.keys #=> ["bar"] key2 = nil # remove the other reference to key GC.start m[key2] #=> nil m.keys #=> []
(Note that GC.start
is used here only for demonstrational purposes and might not always lead to demonstrated results.)
See also ObjectSpace::WeakKeyMap
map class, which compares keys by value, and holds weak references only to the keys.
Public Instance Methods
Source
static VALUE wmap_aref(VALUE self, VALUE key) { VALUE obj = wmap_lookup(self, key); return !UNDEF_P(obj) ? obj : Qnil; }
Returns the value associated with the given key
if found.
If key
is not found, returns nil
.
Source
static VALUE wmap_aset(VALUE self, VALUE key, VALUE val) { struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); VALUE pair[2] = { key, val }; st_update(w->table, (st_data_t)pair, wmap_aset_replace, (st_data_t)pair); RB_OBJ_WRITTEN(self, Qundef, key); RB_OBJ_WRITTEN(self, Qundef, val); return Qnil; }
Associates the given value
with the given key
.
If the given key
exists, replaces its value with the given value
; the ordering is not affected.
Source
static VALUE wmap_delete(VALUE self, VALUE key) { struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); VALUE orig_key = key; st_data_t orig_key_data = (st_data_t)&orig_key; st_data_t orig_val_data; if (st_delete(w->table, &orig_key_data, &orig_val_data)) { VALUE orig_val = *(VALUE *)orig_val_data; rb_gc_remove_weak(self, (VALUE *)orig_key_data); rb_gc_remove_weak(self, (VALUE *)orig_val_data); struct weakmap_entry *entry = (struct weakmap_entry *)orig_key_data; ruby_sized_xfree(entry, sizeof(struct weakmap_entry)); if (wmap_live_p(orig_val)) { return orig_val; } } if (rb_block_given_p()) { return rb_yield(key); } else { return Qnil; } }
Deletes the entry for the given key
and returns its associated value.
If no block is given and key
is found, deletes the entry and returns the associated value:
m = ObjectSpace::WeakMap.new key = "foo" m[key] = 1 m.delete(key) # => 1 m[key] # => nil
If no block is given and key
is not found, returns nil
.
If a block is given and key
is found, ignores the block, deletes the entry, and returns the associated value:
m = ObjectSpace::WeakMap.new key = "foo" m[key] = 2 m.delete(key) { |key| raise 'Will never happen'} # => 2
If a block is given and key
is not found, yields the key
to the block and returns the block’s return value:
m = ObjectSpace::WeakMap.new m.delete("nosuch") { |key| "Key #{key} not found" } # => "Key nosuch not found"
Source
static VALUE wmap_each(VALUE self) { struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); wmap_foreach(w, wmap_each_i, (st_data_t)0); return self; }
Iterates over keys and values. Note that unlike other collections, each
without block isn’t supported.
Source
static VALUE wmap_each_key(VALUE self) { struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); wmap_foreach(w, wmap_each_key_i, (st_data_t)0); return self; }
Iterates over keys. Note that unlike other collections, each_key
without block isn’t supported.
Source
static VALUE wmap_each_value(VALUE self) { struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); wmap_foreach(w, wmap_each_value_i, (st_data_t)0); return self; }
Iterates over values. Note that unlike other collections, each_value
without block isn’t supported.
Source
static VALUE wmap_inspect(VALUE self) { VALUE c = rb_class_name(CLASS_OF(self)); struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); VALUE str = rb_sprintf("-<%"PRIsVALUE":%p", c, (void *)self); wmap_foreach(w, wmap_inspect_i, (st_data_t)str); RSTRING_PTR(str)[0] = '#'; rb_str_cat2(str, ">"); return str; }
Returns true
if key
is a key in self
, otherwise false
.
Source
static VALUE wmap_keys(VALUE self) { struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); VALUE ary = rb_ary_new(); wmap_foreach(w, wmap_keys_i, (st_data_t)ary); return ary; }
Returns a new Array
containing all keys in the map.
Source
static VALUE wmap_size(VALUE self) { struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); st_index_t n = st_table_size(w->table); #if SIZEOF_ST_INDEX_T <= SIZEOF_LONG return ULONG2NUM(n); #else return ULL2NUM(n); #endif }
Returns the number of referenced objects
Source
static VALUE wmap_values(VALUE self) { struct weakmap *w; TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w); VALUE ary = rb_ary_new(); wmap_foreach(w, wmap_values_i, (st_data_t)ary); return ary; }
Returns a new Array
containing all values in the map.