5 comments
on commit 9c857db

I recently asked a question on stackoverflow about rebinding self on a proc that takes a block, and the solution given was to use the Proc#bind method that you just depreciated. Since instance_exec doesn't fully replace it, is it a good idea to depreciate it? I thought a better solution would be to check if the Proc takes a block. If it doesn't, then call instance_exec, otherwise use the existing method. That would stop the majority of leaks (in cases where the Proc doesn't take a block), but not reduce functionality. I was thinking something like this:

@nanothief the problem with bind is that it can create a lot of symbols, I'm not sure how does your code can prevent that. If you need Proc.bind and it works for you, please extract it to a gem or move to you application.

For every invocation of bind, this is creating a unique symbol to create the method with. This does leak very quickly, the code:

1000000.times do
p = Proc.new { |a,b| a * b }
p = p.bind("hello")
end

Takes 31 seconds to run for me, and at its peak consumes 210MB of memory.

To fix this, I wrote a version that only uses one symbol. It is a fairly unique symbol, meaning it would be pretty unlikely for it to be added to another class. Even if it is, the program will capture the old method and rebind it after the method is finished. This version takes 13 seconds to run the above code, and the memory used didn't vary much from between 25-35MB.

It will be fine, as the new method is removed before the bind method finishes.

However thinking about that, in a multithreaded situation, you could hit problems. I couldn't manage to produce a situation where it would produce incorrect output, however the following could be safer: