Skip to content

Instantly share code, notes, and snippets.

@ahoward
Created February 17, 2011 17:41
Show Gist options
  • Save ahoward/832221 to your computer and use it in GitHub Desktop.
Save ahoward/832221 to your computer and use it in GitHub Desktop.
module InstanceExec
Code = lambda do
unless Object.new.respond_to?(:instance_exec)
module InstanceExecHelper; end
include InstanceExecHelper
def instance_exec(*args, &block)
begin
old_critical, Thread.critical = Thread.critical, true
n = 0
n += 1 while respond_to?(mname="__instance_exec_#{ n }__")
InstanceExecHelper.module_eval{ define_method(mname, &block) }
ensure
Thread.critical = old_critical
end
begin
ret = send(mname, *args)
ensure
InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil
end
ret
end
end
end
def InstanceExec.included(other)
other.module_eval(&Code)
super
end
def InstanceExec.extend_object(other)
other.instance_eval(&Code)
super
end
end
if __FILE__ == $0
class C
include InstanceExec
def foo(x) p x end
end
a = C.new
b = Object.new
def b.foo(x) p x end
b.extend(InstanceExec)
callback =
lambda do |x|
p self
p x
end
a.instance_exec(42, &callback)
b.instance_exec(42, &callback)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment