From: transfire@... Date: 2006-07-11T05:35:59+09:00 Subject: Re: instance_exec Mauricio Fernandez wrote: > Here's an improved (hastily written, not thoroughly tested) version: Okay, I took your draft and worked on it some more and came up with the following, but there's something very strange.... require 'thread' class Object module TemporaryMethods; end include TemporaryMethods end class Proc # Creates a local method based on a Proc. def to_method(name=nil, recv=nil) recv ||= eval("self", self) klass = name ? recv.class : TemporaryMethods begin old, Thread.critical = Thread.critical, true unless name n = 0 n += 1 while klass.method_defined?(name = "__to_method_#{n}") #n += 1 while recv.respond_to?(name = "__to_method_#{n}") end me = self klass.module_eval{ define_method(name, &me) } recv.method(name) #if klass == TemporaryMethods ensure if klass == TemporaryMethods klass.module_eval{ remove_method(name) } #rescue nil } #klass.module_eval{ undef_method(name) } #rescue nil } end Thread.critical = old end end end Notice the two remarks on n+=1... and klass.module_eval...., if you unremark the first one, the one with recv.respond_to? it doesn't alwasy see that the method has been removed -- I have to idea why that is since it certainly has been. If you use undef_method instead of remove_method, it work again though! That really blows my min b/c I though undef_method didn;t actually remove the method. So I'm really confused about that. Here's the test I use for the Symbols: # This is dependent on other tests! Be aware! def test_memory a = 2 tproc = proc { |x| x + a } 100.times { tmethod = tproc.to_method assert_equal( 3, tmethod.call(1) ) } meths = Symbol.all_symbols.select { |s| s.to_s =~ /^__to_method/ } assert_equal( 1, meths.size ) end Also is the 'resuce nil' really needed? T. P.S. Is there any reason you use module_eval { define_method... rather then send(:defined_method?...