# Block Trouble (Binding Issue?)

**URL:** <https://www.ruby-forum.com/t/block-trouble-binding-issue/104579>\
**Category:** Ruby\
**Created:** [May 19, 2007, 9:39pm UTC](https://www.ruby-forum.com/t/block-trouble-binding-issue/104579 "2007-05-19T21:39:19Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![illusoft](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/94ad74/32.png) [@illusoft](https://www.ruby-forum.com/u/illusoft)\
**Post date:** [May 19, 2007, 9:39pm UTC](https://www.ruby-forum.com/t/block-trouble-binding-issue/104579/1 "2007-05-19T21:39:19Z")

</div>

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.

Here’s a sample case:

############  
class BlockTester  
def x  
“Correct Method!”  
end

def self.x  
“WRONG METHOD!”  
end

def self.meth(name, &b)  
# … do some stuff  
define\_method name, &b  
end

def self.normal\_meth(name, &b)  
meth(name, &b)  
end

def self.special\_meth(name, &b)  
meth(name) do  
# do something special  
yield # \<= This is the problematic call  
end  
end  
end

# Test Case

class Foo \< BlockTester  
meth “foo” do x end  
normal\_meth “bar” do x end  
special\_meth “baz” do x end  
end

f = Foo.new  
f.foo # =\> “Correct Method!”  
f.bar # =\> “Correct Method!”  
f.baz # =\> “WRONG METHOD!”  
############

The goal, as may not be immediately apparent from the code, is for  
“special\_meth” to be able to create a new method that automatically  
executes a few lines of code before executing the block. While this  
is similar in principle to overriding a method in a subclass…

############  
class X  
def to\_s  
“green” + super  
end  
end  
############

… I can’t seem to make this very common pattern stick for a block.  
Any suggestions?

---

<div class="post-metadata">

**Author:** ![illusoft](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/94ad74/32.png) [@illusoft](https://www.ruby-forum.com/u/illusoft)\
**Post date:** [May 19, 2007, 10:37pm UTC](https://www.ruby-forum.com/t/block-trouble-binding-issue/104579/2 "2007-05-19T22:37:26Z")

</div>

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)…

> def self.special\_meth(name, &b)  
> meth(name) do  
> # do something special  
> yield # \<= This is the problematic call  
> instance\_eval(&b)

---

<div class="post-metadata">

**Author:** ![illusoft](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/94ad74/32.png) [@illusoft](https://www.ruby-forum.com/u/illusoft)\
**Post date:** [May 19, 2007, 11:02pm UTC](https://www.ruby-forum.com/t/block-trouble-binding-issue/104579/3 "2007-05-19T23:02:28Z")

</div>

Arg. Thanks. I would have sworn I tried that at some point. Works  
like a charm.

---

<div class="post-metadata">

**Author:** ![illusoft](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/94ad74/32.png) [@illusoft](https://www.ruby-forum.com/u/illusoft)\
**Post date:** [May 19, 2007, 11:24pm UTC](https://www.ruby-forum.com/t/block-trouble-binding-issue/104579/4 "2007-05-19T23:24:30Z")

</div>

On 5/19/07, Joel VanderWerf [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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 F.’ Eigenclass. Hopefully he does  
not mind that I post this slightly modified version. The original can  
be found here [eigenclass.org](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
