Skip to content

Instantly share code, notes, and snippets.

@niamster
Created April 6, 2015 20:13
Show Gist options
  • Save niamster/37fecc6f895bb58ea927 to your computer and use it in GitHub Desktop.
Save niamster/37fecc6f895bb58ea927 to your computer and use it in GitHub Desktop.
Undead blocks
#!/usr/bin/env ruby
require 'weakref'
class Proxy < BasicObject
attr_reader :cls
def initialize(cls)
@cls = cls
end
def method_missing(meth, *args, &block)
cls.public_send(meth, *args, &block)
end
end
class Hidden
attr_reader :proxy
def self.pcls(cls)
Proc.new {p cls}
end
def initialize(cls)
@cls = cls
@proxy = Proxy.new(cls)
if true # if true then reference to `cls` is never released
self.class.send(:define_method, 'cls') do |*args, &block|
p @cls
end
else
self.class.send(:define_method, 'cls', &Hidden.pcls(cls))
end
end
end
class Test
attr_reader :foo
def initialize(foo)
@foo = foo
end
def self.new(*args, &block)
proxy = Hidden.new(allocate).proxy
proxy.send(:initialize, *args, &block)
proxy
end
end
test = Test.new 'foo'
p test.foo
weak = WeakRef.new test
test = nil
puts 'Wait'
loop do
GC.start
break unless weak.weakref_alive?
end
puts 'PASS' unless weak.weakref_alive?
sleep 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment