Take this example Proc:
proc = Proc.new {|x,y,&block| block.call(x,y,self.instance_method)}
It takes two arguments, x and y, and also a block.
I want to execute that block using different values for self. Something like this nearly works:
some_object.instance_exec("x arg", "y arg", &proc)
However that doesn’t allow you to pass in a block. This also doesn’t work
some_object.instance_exec("x arg", "y arg", another_proc, &proc)
nor does
some_object.instance_exec("x arg", "y arg", &another_proc, &proc)
I’m not sure what else could work here. Is this possible, and if so how do you do it?
Edit: Basically if you can get this rspec file to pass by changing the change_scope_of_proc method, you have solved my problem.
require 'rspec'
class SomeClass
def instance_method(x)
"Hello #{x}"
end
end
class AnotherClass
def instance_method(x)
"Goodbye #{x}"
end
def make_proc
Proc.new do |x, &block|
instance_method(block.call(x))
end
end
end
def change_scope_of_proc(new_self, proc)
# TODO fix me!!!
proc
end
describe "change_scope_of_proc" do
it "should change the instance method that is called" do
some_class = SomeClass.new
another_class = AnotherClass.new
proc = another_class.make_proc
fixed_proc = change_scope_of_proc(some_class, proc)
result = fixed_proc.call("Wor") do |x|
"#{x}ld"
end
result.should == "Hello World"
end
end
To solve this, you need to re-bind the Proc to the new class.
Here’s your solution, leveraging some good code from Rails core_ext: