class ObjectSpace::WeakKeyMap
An ObjectSpace::WeakKeyMap
object holds references to any objects, but objects uses as keys can be garbage collected.
Objects used as values can’t be garbage collected until the key is.
Public Instance Methods
Returns the value associated with the given key
if found.
If key
is not found, returns nil
.
static VALUE wkmap_aref(VALUE self, VALUE key) { VALUE obj = wkmap_lookup(self, key); return obj != Qundef ? obj : Qnil; }
Associates the given value
with the given key
; returns value
.
The reference to key
is weak, so when there is no other reference to key
it may be garbage collected.
If the given key
exists, replaces its value with the given value
; the ordering is not affected
static VALUE wkmap_aset(VALUE self, VALUE key, VALUE val) { struct weakkeymap *w; TypedData_Get_Struct(self, struct weakkeymap, &weakkeymap_type, w); if (!FL_ABLE(key) || SYMBOL_P(key) || RB_BIGNUM_TYPE_P(key) || RB_TYPE_P(key, T_FLOAT)) { rb_raise(rb_eArgError, "WeakKeyMap must be garbage collectable"); UNREACHABLE_RETURN(Qnil); } struct wkmap_aset_args args = { .new_key = key, .new_val = val, }; st_update(w->table, (st_data_t)&key, wkmap_aset_replace, (st_data_t)&args); RB_OBJ_WRITTEN(self, Qundef, key); RB_OBJ_WRITTEN(self, Qundef, val); return val; }
Removes all map entries; returns self
.
static VALUE wkmap_clear(VALUE self) { struct weakkeymap *w; TypedData_Get_Struct(self, struct weakkeymap, &weakkeymap_type, w); st_foreach(w->table, wkmap_free_table_i, 0); st_clear(w->table); return self; }
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::WeakKeyMap.new m["foo"] = 1 m.delete("foo") # => 1 m["foo"] # => nil
If no block 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::WeakKeyMap.new m["foo"] = 2 h.delete("foo") { |key| raise 'Will never happen'} # => 2
If a block is given and key
is not found, calls the block and returns the block’s return value:
m = ObjectSpace::WeakKeyMap.new h.delete("nosuch") { |key| "Key #{key} not found" } # => "Key nosuch not found"
static VALUE wkmap_delete(VALUE self, VALUE key) { struct weakkeymap *w; TypedData_Get_Struct(self, struct weakkeymap, &weakkeymap_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); ruby_sized_xfree((VALUE *)orig_key_data, sizeof(VALUE)); return orig_val; } if (rb_block_given_p()) { return rb_yield(key); } else { return Qnil; } }
Returns the existing equal key if it exists, otherwise returns nil
.
static VALUE wkmap_getkey(VALUE self, VALUE key) { struct weakkeymap *w; TypedData_Get_Struct(self, struct weakkeymap, &weakkeymap_type, w); st_data_t orig_key; if (!st_get_key(w->table, (st_data_t)&key, &orig_key)) return Qnil; return *(VALUE *)orig_key; }
Returns a new String
containing informations about the map:
m = ObjectSpace::WeakKeyMap.new m[key] = value m.inspect # => "#<ObjectSpace::WeakKeyMap:0x00000001028dcba8 size=1>"
static VALUE wkmap_inspect(VALUE self) { struct weakkeymap *w; TypedData_Get_Struct(self, struct weakkeymap, &weakkeymap_type, w); st_index_t n = st_table_size(w->table); #if SIZEOF_ST_INDEX_T <= SIZEOF_LONG const char * format = "#<%"PRIsVALUE":%p size=%lu>"; #else const char * format = "#<%"PRIsVALUE":%p size=%llu>"; #endif VALUE str = rb_sprintf(format, rb_class_name(CLASS_OF(self)), (void *)self, n); return str; }
Returns true
if key
is a key in self
, otherwise false
.
static VALUE wkmap_has_key(VALUE self, VALUE key) { return RBOOL(wkmap_lookup(self, key) != Qundef); }