mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Initial revision
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3db12e8b23
commit
62e41d3f2e
56 changed files with 13850 additions and 0 deletions
70
lib/weakref.rb
Normal file
70
lib/weakref.rb
Normal file
|
@ -0,0 +1,70 @@
|
|||
# Weak Reference class that does not bother GCing.
|
||||
#
|
||||
# Usage:
|
||||
# foo = Object.new
|
||||
# foo.hash
|
||||
# foo = WeakRef.new(foo)
|
||||
# foo.hash
|
||||
# ObjectSpace.garbage_collect
|
||||
# foo.hash # => Raises WeakRef::RefError (because original GC'ed)
|
||||
|
||||
require "delegate"
|
||||
|
||||
class WeakRef<Delegater
|
||||
|
||||
Exception :RefError
|
||||
|
||||
ID_MAP = {}
|
||||
ID_REV_MAP = {}
|
||||
ObjectSpace.add_finalizer(lambda{|id|
|
||||
rid = ID_MAP[id]
|
||||
if rid
|
||||
ID_REV_MAP[rid] = nil
|
||||
ID_MAP[id] = nil
|
||||
end
|
||||
rid = ID_REV_MAP[id]
|
||||
if rid
|
||||
ID_REV_MAP[id] = nil
|
||||
ID_MAP[rid] = nil
|
||||
end
|
||||
})
|
||||
|
||||
def initialize(orig)
|
||||
super
|
||||
@id = orig.id
|
||||
ObjectSpace.call_finalizer orig
|
||||
ID_MAP[@id] = self.id
|
||||
ID_REV_MAP[self.id] = @id
|
||||
end
|
||||
|
||||
def __getobj__
|
||||
unless ID_MAP[@id]
|
||||
$@ = caller(1)
|
||||
$! = RefError.new("Illegal Reference - probably recycled")
|
||||
raise
|
||||
end
|
||||
ObjectSpace.id2ref(@id)
|
||||
# ObjectSpace.each_object do |obj|
|
||||
# return obj if obj.id == @id
|
||||
# end
|
||||
end
|
||||
|
||||
def weakref_alive?
|
||||
if ID_MAP[@id]
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def []
|
||||
__getobj__
|
||||
end
|
||||
end
|
||||
|
||||
foo = Object.new
|
||||
p foo.hash
|
||||
foo = WeakRef.new(foo)
|
||||
p foo.hash
|
||||
ObjectSpace.garbage_collect
|
||||
p foo.hash
|
Loading…
Add table
Add a link
Reference in a new issue