From: Robert Dober Date: 2007-05-20T06:22:53+09:00 Subject: Re: Block Trouble (Binding Issue?) On 5/19/07, Joel VanderWerf wrote: > Pieter V. wrote: > > I'm presently trying to work on a little metaprogramming project, but > > am finding my efforts a little frustrated by ... well, I'm not rightly > > sure what by. It seems to be a scoping issue, from what I can tell. > > Yup, it sure is. define_method(name, &block) changes the scope of block > to the instance, but the yield still references a block in class Foo scope. > > A fix might be to replace yield with instance_eval(&b), as below, but > that will preclude passing arguments to the block, in case you ever need > to do that. Google for instance_exec for a discussion, hacks for the > present, and hope for the future (1.9 has it)... As we just had a discussion about it maybe you might be interested in this, it comes from Mauricio Fernandez' Eigenclass. Hopefully he does not mind that I post this slightly modified version. The original can be found here http://eigenclass.org/hiki/bounded+space+instance_exec there is very good stuff over there. Especially as you are interested in metaprogramming. All I added to Mauricio's code is to remove the temporary method *before* calling it, thus avoiding a theoretical possibility of endless recursion in the temporary method call. class Object include InstanceExecHelper = Module.new 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) } mthd = method(mname) InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil ensure Thread.critical = old_critical end mthd.call *args end end . HTH Robert -- You see things; and you say Why? But I dream things that never were; and I say Why not? -- George Bernard Shaw