класс WeakRef
Класс слабой ссылки, позволяющий объекту-цели быть удалённым сборщиком мусора.
Объект WeakRef может быть использован точно так же, как и объект, на который он ссылается.
Использование:
foo = Object.new # create a new object instance p foo.to_s # original's class foo = WeakRef.new(foo) # reassign foo with WeakRef instance p foo.to_s # should be same class GC.start # start the garbage collector p foo.to_s # should raise exception (recycled)
Пример
С помощью WeakRef мы можем реализовать собственный примитивный класс WeakHash.
Мы назовём его WeakHash, так как он по сути является Hash, за исключением того, что все его ключи и значения могут быть удалены сборщиком мусора.
require 'weakref'
class WeakHash < Hash
def []= key, obj
super WeakRef.new(key), WeakRef.new(obj)
end
end
Это всего лишь простое реализация. Мы открыли класс Hash и изменили метод Hash#store, чтобы он создавал новый объект WeakRef с параметрами key и obj перед передачей их как пары ключ-значение в хэш.
В этом случае вам придётся ограничиться строковыми ключами, иначе вы получите исключение ArgumentError, так как WeakRef не может создать финализатор для Symbol. Символы неизменяемы и не могут быть удалены сборщиком мусора.
Посмотрим, как это работает:
omg = "lol"
c = WeakHash.new
c['foo'] = "bar"
c['baz'] = Object.new
c['qux'] = omg
puts c.inspect
#=> {"foo"=>"bar", "baz"=>#<Object:0x007f4ddfc6cb48>, "qux"=>"lol"}
# Now run the garbage collector
GC.start
c['foo'] #=> nil
c['baz'] #=> nil
c['qux'] #=> nil
omg #=> "lol"
puts c.inspect
#=> WeakRef::RefError: Invalid Reference - probably recycled
Вы можете видеть, что локальная переменная omg осталась, хотя её ссылка в объекте хэша была удалена сборщиком мусора, вместе с остальными ключами и значениями. Также, когда мы попытались получить доступ к нашему хэшу, мы получили исключение WeakRef::RefError. Это связано с тем, что эти объекты также были удалены сборщиком мусора.
Публичные методы класса
# File lib/weakref.rb, line 82
def initialize(orig)
case orig
when true, false, nil
@delegate_sd_obj = orig
else
@@__map[self] = orig
end
super
end Создаёт слабую ссылку на orig
Вызывает исключение ArgumentError, если заданный orig является неизменяемым, например, Symbol, Integer или Float.
Публичные методы экземпляра
# File lib/weakref.rb, line 103 def weakref_alive? @@__map.key?(self) or defined?(@delegate_sd_obj) end
Возвращает true, если ссылка на объект всё ещё активна.
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.