Spec-Zone.ru › Ruby 2.4

класс WeakRef

Родитель:
Delegator

Класс слабой ссылки, позволяющий объекту-цели быть удалённым сборщиком мусора.

Объект 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. Это связано с тем, что эти объекты также были удалены сборщиком мусора.

Публичные методы класса

new(orig) Показать исходный код
# 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.

Вызывает метод суперкласса Delegator.new

Публичные методы экземпляра

weakref_alive?() Показать исходный код
# 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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API