Class: ObjectSpace::WeakMap
- Includes:
- Enumerable
- Defined in:
- weakmap.c,
 weakmap.c
Overview
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.
Instance Method Summary collapse
- 
  
    
      #[](key)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Returns the value associated with the given keyif found.
- 
  
    
      #[]=(key)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Associates the given valuewith the givenkey.
- 
  
    
      #delete(key)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Deletes the entry for the given keyand returns its associated value.
- 
  
    
      #each {|key, val| ... } ⇒ self 
    
    
  
  
  
  
  
  
  
  
  
    Iterates over keys and values. 
- 
  
    
      #each_key {|key| ... } ⇒ self 
    
    
  
  
  
  
  
  
  
  
  
    Iterates over keys. 
- 
  
    
      #each {|key, val| ... } ⇒ self 
    
    
  
  
  
  
  
  
  
  
  
    Iterates over keys and values. 
- 
  
    
      #each_value {|val| ... } ⇒ self 
    
    
  
  
  
  
  
  
  
  
  
    Iterates over values. 
- 
  
    
      #key?(key)  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    Returns trueifkeyis a key inself, otherwisefalse.
- #inspect ⇒ Object
- 
  
    
      #key?(key)  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    Returns trueifkeyis a key inself, otherwisefalse.
- 
  
    
      #keys  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Returns a new Array containing all keys in the map. 
- 
  
    
      #size  ⇒ Numeric 
    
    
  
  
  
  
  
  
  
  
  
    Returns the number of referenced objects. 
- 
  
    
      #key?(key)  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    Returns trueifkeyis a key inself, otherwisefalse.
- 
  
    
      #size  ⇒ Numeric 
    
    
  
  
  
  
  
  
  
  
  
    Returns the number of referenced objects. 
- 
  
    
      #values  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Returns a new Array containing all values in the map. 
Methods included from Enumerable
#all?, #any?, #chain, #chunk, #chunk_while, #collect, #collect_concat, #compact, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #filter, #filter_map, #find, #find_all, #find_index, #first, #flat_map, #grep, #grep_v, #group_by, #inject, #lazy, #map, #max, #max_by, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reduce, #reject, #reverse_each, #select, #slice_after, #slice_before, #slice_when, #sort, #sort_by, #sum, #take, #take_while, #tally, #to_a, #to_h, #uniq, #zip
Instance Method Details
#[](key) ⇒ Object
Returns the value associated with the given key if found.
If key is not found, returns nil.
| 514 515 516 517 518 519 | # File 'weakmap.c', line 514
static VALUE
wmap_aref(VALUE self, VALUE key)
{
    VALUE obj = wmap_lookup(self, key);
    return !UNDEF_P(obj) ? obj : Qnil;
} | 
#[]=(key) ⇒ Object
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.
| 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | # File 'weakmap.c', line 473
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;
} | 
#delete(key) ⇒ nil #delete(key) {|key| ... } ⇒ Object
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"
| 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 | # File 'weakmap.c', line 549
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;
    }
} | 
#each {|key, val| ... } ⇒ self
Iterates over keys and values. Note that unlike other collections, each without block isn’t supported.
| 319 320 321 322 323 324 325 326 327 328 | # File 'weakmap.c', line 319
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;
} | 
#each_key {|key| ... } ⇒ self
Iterates over keys. Note that unlike other collections, each_key without block isn’t supported.
| 346 347 348 349 350 351 352 353 354 355 | # File 'weakmap.c', line 346
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;
} | 
#each {|key, val| ... } ⇒ self
Iterates over keys and values. Note that unlike other collections, each without block isn’t supported.
| 319 320 321 322 323 324 325 326 327 328 | # File 'weakmap.c', line 319
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;
} | 
#each_value {|val| ... } ⇒ self
Iterates over values. Note that unlike other collections, each_value without block isn’t supported.
| 373 374 375 376 377 378 379 380 381 382 | # File 'weakmap.c', line 373
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;
} | 
#key?(key) ⇒ Boolean
Returns true if key is a key in self, otherwise false.
| 586 587 588 589 590 | # File 'weakmap.c', line 586
static VALUE
wmap_has_key(VALUE self, VALUE key)
{
    return RBOOL(!UNDEF_P(wmap_lookup(self, key)));
} | 
#inspect ⇒ Object
| 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | # File 'weakmap.c', line 286
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;
} | 
#key?(key) ⇒ Boolean
Returns true if key is a key in self, otherwise false.
| 586 587 588 589 590 | # File 'weakmap.c', line 586
static VALUE
wmap_has_key(VALUE self, VALUE key)
{
    return RBOOL(!UNDEF_P(wmap_lookup(self, key)));
} | 
#keys ⇒ Object
Returns a new Array containing all keys in the map.
| 401 402 403 404 405 406 407 408 409 410 411 | # File 'weakmap.c', line 401
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;
} | 
#size ⇒ Numeric
Returns the number of referenced objects
| 598 599 600 601 602 603 604 605 606 607 608 609 610 611 | # File 'weakmap.c', line 598
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
} | 
#key?(key) ⇒ Boolean
Returns true if key is a key in self, otherwise false.
| 586 587 588 589 590 | # File 'weakmap.c', line 586
static VALUE
wmap_has_key(VALUE self, VALUE key)
{
    return RBOOL(!UNDEF_P(wmap_lookup(self, key)));
} | 
#size ⇒ Numeric
Returns the number of referenced objects
| 598 599 600 601 602 603 604 605 606 607 608 609 610 611 | # File 'weakmap.c', line 598
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
} | 
#values ⇒ Object
Returns a new Array containing all values in the map.
| 430 431 432 433 434 435 436 437 438 439 440 | # File 'weakmap.c', line 430
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;
} |