On Mon, Jul 10, 2006 at 10:44:32PM +0900, transfire / gmail.com wrote:
> Duh! I'm sitting here screwing with this and the answer's sitting one
> directory over.. with only a minor modification (I added recv=nil) I
> introduce you to Facets' Proc#to_method:
> 
>   #--
>   # Credit for #to_method goes to Forian Gross (flgr).
                                    (Florian)
>   #--
> 
>   require 'thread'
> 
>   class Proc
> 
>     MethodMutexes = Hash.new do |hash, key|
>       hash[key] = Mutex.new
>     end
> 
>     # Creates a local method based on a Proc.
>     def to_method(name=nil, recv=nil)
>       name ||= "!to_method_temp#{self.object_id}"
                  ================================

This can create a lot of different symbols, leading to large memory leaks.

>       recv ||= eval("self", self)
>       klass = recv.class
>       MethodMutexes[klass => name].synchronize do
        ============================

This makes the memleak even heavier, going from potentially ~70 bytes to
nearly 300 bytes per call...

>         begin
>           klass.send(:define_method, name, &self)
            ==========

This will fail if the class was frozen.

See my blog for a better implementation.

>           return recv.method(name)
>         ensure
>           klass.send(:remove_method, name) if not name
>         end
>       end
>     end
> 
>   end

-- 
Mauricio Fernandez  -   http://eigenclass.org   -  singular Ruby