# Instance\_eval with a block

**URL:** <https://rubytalk.org/t/instance-eval-with-a-block/1712>\
**Category:** ruby-talk\
**Created:** [11 September 2002 23:22 UTC](https://rubytalk.org/t/instance-eval-with-a-block/1712 "2002-09-11T23:22:07Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brad\_Hilton](https://avatars.discourse-cdn.com/v4/letter/b/0ea827/32.png) [@Brad\_Hilton](https://rubytalk.org/u/Brad_Hilton)\
**Post date:** [11 September 2002 23:22 UTC](https://rubytalk.org/t/instance-eval-with-a-block/1712/1 "2002-09-11T23:22:07Z")

</div>

Hello,

Can someone please explain why the following code doesn’t work?

P.S. If I move the methods out of class ‘TestEval’, things work as  
expected. I’m guessing it has to do with Binding or some such trickery,  
but I’m stumped.

Thanks,  
-Brad

> **···**
>
> * * *
> 
> class TestEval  
> def install\_attrs(attrs)  
> attrs.each { |k, v|  
> type.send(:attr\_accessor, k)  
> send("#{k}=", v)  
> }  
> end
> 
> def output(params, block)  
> install\_attrs(params)  
> instance\_eval { block.call }  
> end  
> end # class TestEval
> 
> block = proc { @name }
> 
> test = TestEval.new
> 
> params = {  
> ‘name’ =\> ‘Joe’,  
> }
> 
> puts test.output(params, block)
> 
> params[‘name’] = 'Marty’  
> puts test.output(params, block)
> 
> * * *

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [11 September 2002 23:45 UTC](https://rubytalk.org/t/instance-eval-with-a-block/1712/2 "2002-09-11T23:45:07Z")

</div>

See embedded comments:

Brad Hilton wrote:

> Hello,
> 
> Can someone please explain why the following code doesn’t work?
> 
> P.S. If I move the methods out of class ‘TestEval’, things work as  
> expected. I’m guessing it has to do with Binding or some such trickery,  
> but I’m stumped.
> 
> Thanks,  
> -Brad
> 
> * * *
> 
> class TestEval  
> def install\_attrs(attrs)  
> attrs.each { |k, v|  
> type.send(:attr\_accessor, k)  
> send(“#{k}=”, v)  
> }  
> end
> 
> def output(params, block)  
> install\_attrs(params)  
> instance\_eval { block.call }

```
   instance_eval &block # Fixes it. This changes the "self"
                         # binding for block.

```

> end  
> end # class TestEval

@name = “FOO” # This is what the @name below was getting bound  
# to, and “block.call” preserved that binding.

> **···**
>
> > block = proc { @name }
> > 
> > test = TestEval.new
> > 
> > params = {  
> > ‘name’ =\> ‘Joe’,  
> > }
> > 
> > puts test.output(params, block)
> > 
> > params[‘name’] = ‘Marty’  
> > puts test.output(params, block)
> > 
> > * * *
> 
> –  
> Joel VanderWerf California PATH, UC Berkeley  
> [mailto:vjoel@path.berkeley.edu](mailto:vjoel@path.berkeley.edu) Ph. (510) 231-9446  
> [http://www.path.berkeley.edu](http://www.path.berkeley.edu) FAX (510) 231-9512
