Class: WeakRef
- Inherits:
-
Delegator
- Object
- Delegator
- WeakRef
- Defined in:
- lib/weakref.rb
Overview
WeakRef is a class to represent a reference to an object that is not seen by the tracing phase of the garbage collector. This allows the referenced object to be garbage collected as if nothing is referring to it. Because WeakRef delegates method calls to the referenced object, it may be used in place of that object, i.e. it is of the same duck type.
Usage:
foo = Object.new
foo = Object.new
p foo.to_s # original's class
foo = WeakRef.new(foo)
p foo.to_s # should be same class
ObjectSpace.garbage_collect
p foo.to_s # should raise exception (recycled)
Defined Under Namespace
Classes: RefError
Constant Summary collapse
- @@id_map =
{}
- @@id_rev_map =
obj -> [ref,...] ref -> obj
{}
- @@final =
lambda{|id| __old_status = Thread.critical Thread.critical = true begin rids = @@id_map[id] if rids for rid in rids @@id_rev_map.delete(rid) end @@id_map.delete(id) end rid = @@id_rev_map[id] if rid @@id_rev_map.delete(id) @@id_map[rid].delete(id) @@id_map.delete(rid) if @@id_map[rid].empty? end ensure Thread.critical = __old_status end }
Instance Method Summary collapse
-
#__getobj__ ⇒ Object
Return the object this WeakRef references.
- #__setobj__(obj) ⇒ Object
-
#initialize(orig) ⇒ WeakRef
constructor
Create a new WeakRef from
orig
. -
#weakref_alive? ⇒ Boolean
Returns true if the referenced object still exists, and false if it has been garbage collected.
Constructor Details
#initialize(orig) ⇒ WeakRef
Create a new WeakRef from orig
.
49 50 51 52 |
# File 'lib/weakref.rb', line 49 def initialize(orig) super __setobj__(orig) end |
Instance Method Details
#__getobj__ ⇒ Object
Return the object this WeakRef references. Raises RefError if the object has been garbage collected. The object returned is the object to which method calls are delegated (see Delegator).
57 58 59 60 61 62 63 64 65 66 |
# File 'lib/weakref.rb', line 57 def __getobj__ unless @@id_rev_map[self.__id__] == @__id raise RefError, "Illegal Reference - probably recycled", caller(2) end begin ObjectSpace._id2ref(@__id) rescue RangeError raise RefError, "Illegal Reference - probably recycled", caller(2) end end |
#__setobj__(obj) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/weakref.rb', line 68 def __setobj__(obj) @__id = obj.__id__ __old_status = Thread.critical begin Thread.critical = true unless @@id_rev_map.key?(self) ObjectSpace.define_finalizer obj, @@final ObjectSpace.define_finalizer self, @@final end @@id_map[@__id] = [] unless @@id_map[@__id] ensure Thread.critical = __old_status end @@id_map[@__id].push self.__id__ @@id_rev_map[self.__id__] = @__id end |
#weakref_alive? ⇒ Boolean
Returns true if the referenced object still exists, and false if it has been garbage collected.
87 88 89 |
# File 'lib/weakref.rb', line 87 def weakref_alive? @@id_rev_map[self.__id__] == @__id end |