类 ObjectSpace::WeakMap

一个 ObjectSpace::WeakMap 是一个键值映射,它对键和值持有弱引用,因此当没有更多引用时,它们可以被垃圾回收。

映射中的键通过标识进行比较。

m = ObjectSpace::WeekMap.new
key1 = "foo"
val1 = Object.new
m[key1] = val1

key2 = "foo"
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 #=> []

(注意,GC.start 这里仅用于演示目的,可能并不总是导致演示的结果。)

另请参见 ObjectSpace::WeakKeyMap 映射类,它通过值比较键,并且只对键持有弱引用。

公共实例方法

map[key] → value 点击切换源代码

如果找到,返回与给定 key 关联的值。

如果未找到 key,则返回 nil

static VALUE
wmap_aref(VALUE self, VALUE key)
{
    VALUE obj = wmap_lookup(self, key);
    return !UNDEF_P(obj) ? obj : Qnil;
}
map[key] = value → value 点击切换源代码

将给定的 value 与给定的 key 关联。

如果给定的 key 存在,则用给定的 value 替换其值;顺序不受影响。

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 nonspecial_obj_id(val);
}
delete(key) → value 或 nil 点击切换源代码
delete(key) {|key| ... } → object

删除给定 key 的条目并返回其关联的值。

如果没有给出块并且找到了 key,则删除条目并返回关联的值

m = ObjectSpace::WeakMap.new
key = "foo"
m[key] = 1
m.delete(key) # => 1
m[key] # => nil

如果没有给出块并且未找到 key,则返回 nil

如果给出块并且找到了 key,则忽略块,删除条目,并返回关联的值

m = ObjectSpace::WeakMap.new
key = "foo"
m[key] = 2
m.delete(key) { |key| raise 'Will never happen'} # => 2

如果给出块并且未找到 key,则将 key 传递给块并返回块的返回值

m = ObjectSpace::WeakMap.new
m.delete("nosuch") { |key| "Key #{key} not found" } # => "Key nosuch not found"
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);

        wmap_free_entry((VALUE *)orig_key_data, (VALUE *)orig_val_data);

        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 点击切换源代码

遍历键值对。请注意,与其他集合不同,each 不支持不带块的使用。

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_pair
each_key {|key| ... } → self 点击切换源代码

遍历键。请注意,与其他集合不同,each_key 不支持不带块的使用。

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_pair()

遍历键值对。请注意,与其他集合不同,each 不支持不带块的使用。

别名:each
each_value {|val| ... } → self 点击切换源代码

遍历值。请注意,与其他集合不同,each_value 不支持不带块的使用。

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;
}
include?(key) -> true or false 点击切换源代码

如果keyself 中的键,则返回true,否则返回false

static VALUE
wmap_has_key(VALUE self, VALUE key)
{
    return RBOOL(!UNDEF_P(wmap_lookup(self, key)));
}
别名:member?, key?
inspect() 点击切换源代码
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) → true or false

如果keyself 中的键,则返回true,否则返回false

别名:include?
keys → new_array 点击切换源代码

返回一个包含映射中所有键的新Array

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;
}
length()

返回被引用对象的个数。

别名:size
member?(p1)

如果keyself 中的键,则返回true,否则返回false

别名:include?
size → number 点击切换源代码

返回被引用对象的个数。

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
}
别名:length
values → new_array 点击切换源代码

返回一个包含映射中所有值的新Array

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;
}