класс 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, Fixnum или 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.