Class: WeakRef

Inherits:
Delegator
  • Object
show all
Defined in:
lib/weakref.rb

Overview

Weak Reference class that allows a referenced object to be garbage-collected. A WeakRef may be used exactly like the object it references.

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

{}
@@mutex =
Mutex.new
@@final =
lambda {|id|
  @@mutex.synchronize {
    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
  }
}

Instance Method Summary collapse

Constructor Details

#initialize(orig) ⇒ WeakRef

Creates a weak reference to orig



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/weakref.rb', line 51

def initialize(orig)
  @__id = orig.object_id
  ObjectSpace.define_finalizer orig, @@final
  ObjectSpace.define_finalizer self, @@final
  @@mutex.synchronize {
    @@id_map[@__id] = [] unless @@id_map[@__id]
  }
  @@id_map[@__id].push self.object_id
  @@id_rev_map[self.object_id] = @__id
  super
end

Instance Method Details

#__getobj__Object

:nodoc:



63
64
65
66
67
68
69
70
71
72
# File 'lib/weakref.rb', line 63

def __getobj__ # :nodoc:
  unless @@id_rev_map[self.object_id] == @__id
    Kernel::raise RefError, "Invalid Reference - probably recycled", Kernel::caller(2)
  end
  begin
    ObjectSpace._id2ref(@__id)
  rescue RangeError
    Kernel::raise RefError, "Invalid Reference - probably recycled", Kernel::caller(2)
  end
end

#__setobj__(obj) ⇒ Object

:nodoc:



74
75
# File 'lib/weakref.rb', line 74

def __setobj__(obj) # :nodoc:
end

#weakref_alive?Boolean

Returns true if the referenced object is still alive.

Returns:

  • (Boolean)


80
81
82
# File 'lib/weakref.rb', line 80

def weakref_alive?
  @@id_rev_map[self.object_id] == @__id
end