класс 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, который сравнивает ключи по значению и хранит слабые ссылки только на ключи.
Открытые методы экземпляров
static VALUE
wmap_aref(VALUE self, VALUE key)
{
VALUE obj = wmap_lookup(self, key);
return !UNDEF_P(obj) ? obj : Qnil;
} Возвращает значение, связанное с заданным ключом, если он найден.
Если ключ не найден, возвращает nil.
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);
} Связывает заданное значение с заданным ключом.
Если заданный ключ существует, заменяет его значение заданным значением; порядок не изменяется.
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;
}
} Удаляет запись для данного ключа и возвращает связанное с ним значение.
Если блок не задан и ключ найден, удаляет запись и возвращает связанное значение:
m = ObjectSpace::WeakMap.new key = "foo" m[key] = 1 m.delete(key) # => 1 m[key] # => nil
Если блок не задан и ключ не найден, возвращает nil.
Если блок задан и ключ найден, игнорирует блок, удаляет запись и возвращает связанное значение:
m = ObjectSpace::WeakMap.new
key = "foo"
m[key] = 2
m.delete(key) { |key| raise 'Will never happen'} # => 2
Если блок задан и ключ не найден, передаёт ключ в блок и возвращает возвращаемое значение блока:
m = ObjectSpace::WeakMap.new
m.delete("nosuch") { |key| "Key #{key} not found" } # => "Key nosuch not found"
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;
} Итерируется по ключам и значениям. Обратите внимание, что в отличие от других коллекций, метод без блока не поддерживается.
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;
} Итерируется по ключам. Обратите внимание, что в отличие от других коллекций, метод без блока не поддерживается.
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;
} Итерируется по значениям. Обратите внимание, что в отличие от других коллекций, метод без блока не поддерживается.
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;
} Возвращает true если key является ключом в self, иначе false.
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;
} Возвращает новый массив, содержащий все ключи в карте.
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
} Возвращает количество ссылаемых объектов.
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;
} Возвращает новый массив, содержащий все значения в карте.
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.