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 value) { 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_raise(rb_eArgError, "WeakKeyMap must be garbage collectable"); } st_index_t hash = wkmap_lookup_hash(w, key); weakkeymap_entry_t *key_entry = wkmap_lookup_entry(w, key, hash); if (!key_entry) { key_entry = ALLOC(weakkeymap_entry_t); key_entry->obj = key; key_entry->hash = hash; } if (!st_insert(w->map, (st_data_t)key_entry, (st_data_t)value)) { st_insert(w->obj2hash, (st_data_t)key, (st_data_t)hash); rb_define_finalizer_no_check(key, w->final); } RB_OBJ_WRITTEN(self, Qundef, value); return value; }
Removes all map entries; returns self
.
static VALUE wkmap_clear(VALUE self) { struct weakkeymap *w; TypedData_Get_Struct(self, struct weakkeymap, &weakkeymap_type, w); if (w->map) { st_clear(w->map); } if (w->obj2hash) { st_clear(w->obj2hash); } return self; }
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_index_t hash = rb_any_hash(key); weakkeymap_entry_t lookup_entry = {key, hash}; weakkeymap_entry_t *key_entry = NULL; if (st_get_key(w->map, (st_data_t)&lookup_entry, (st_data_t *)&key_entry)) { assert(key_entry != NULL); VALUE obj = key_entry->obj; if (wmap_live_p(obj)) { return obj; } } return Qnil; }
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 = 0; if (w->map) { n = w->map->num_entries; } #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); }