# Pass block instead of here document?

**URL:** <https://rubytalk.org/t/pass-block-instead-of-here-document/32315>\
**Category:** ruby-talk\
**Created:** [25 October 2006 19:31 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315 "2006-10-25T19:31:31Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gavin\_Kistner](https://avatars.discourse-cdn.com/v4/letter/g/ed655f/32.png) [@Gavin\_Kistner](https://rubytalk.org/u/Gavin_Kistner)\
**Post date:** [25 October 2006 19:31 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/1 "2006-10-25T19:31:31Z")

</div>

> I'd rather pass in a block. Is there a way to do that? Something like:
> 
> \<pseud-code\>  
> module Kernel  
> &nbsp;&nbsp;&nbsp;&nbsp;def tell(obj, &to\_do)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# what goes here?  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> end
> 
> tell Foo.new do  
> &nbsp;&nbsp;&nbsp;&nbsp;report  
> &nbsp;&nbsp;&nbsp;&nbsp;eat 'burger', 'fries'  
> &nbsp;&nbsp;&nbsp;&nbsp;drink 'beer'  
> &nbsp;&nbsp;&nbsp;&nbsp;be\_merry  
> end  
> \</pseud-code\>

def tell( obj, &to\_do )  
&nbsp;&nbsp;obj.instance\_eval( &to\_do )  
end

class Foo  
&nbsp;&nbsp;def say\_hi  
&nbsp;&nbsp;&nbsp;&nbsp;p "Hi!"  
&nbsp;&nbsp;end  
end

tell Foo.new do  
&nbsp;&nbsp;say\_hi  
end  
#=\> "Hi!"

> **···**
>
> From: Morton Goldberg [mailto:m\_goldberg@ameritech.net]

---

<div class="post-metadata">

**Author:** ![Morton\_Goldberg](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@Morton\_Goldberg](https://rubytalk.org/u/Morton_Goldberg)\
**Post date:** [25 October 2006 19:45 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/2 "2006-10-25T19:45:29Z")

</div>

It's really that easy? Amazing! Ruby makes things so easy compared with the other languages I've used that I'm constantly inventing hard ways of doing what is too obvious for me to see.

Thanks for your help.

Regards, Morton

> **···**
>
> On Oct 25, 2006, at 3:31 PM, Gavin Kistner wrote:
> 
> > From: Morton Goldberg [mailto:m\_goldberg@ameritech.net]
> > 
> > > I'd rather pass in a block. Is there a way to do that? Something like:
> > > 
> > > \<pseud-code\>  
> > > module Kernel  
> > > &nbsp;&nbsp;&nbsp;&nbsp;def tell(obj, &to\_do)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# what goes here?  
> > > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > > end
> > > 
> > > tell Foo.new do  
> > > &nbsp;&nbsp;&nbsp;&nbsp;report  
> > > &nbsp;&nbsp;&nbsp;&nbsp;eat 'burger', 'fries'  
> > > &nbsp;&nbsp;&nbsp;&nbsp;drink 'beer'  
> > > &nbsp;&nbsp;&nbsp;&nbsp;be\_merry  
> > > end  
> > > \</pseud-code\>
> > 
> > def tell( obj, &to\_do )  
> > &nbsp;&nbsp;obj.instance\_eval( &to\_do )  
> > end
> > 
> > class Foo  
> > &nbsp;&nbsp;def say\_hi  
> > &nbsp;&nbsp;&nbsp;&nbsp;p "Hi!"  
> > &nbsp;&nbsp;end  
> > end
> > 
> > tell Foo.new do  
> > &nbsp;&nbsp;say\_hi  
> > end  
> > #=\> "Hi!"

---

<div class="post-metadata">

**Author:** ![Ken\_Bloom](https://avatars.discourse-cdn.com/v4/letter/k/f08c70/32.png) [@Ken\_Bloom](https://rubytalk.org/u/Ken_Bloom)\
**Post date:** [26 October 2006 00:45 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/3 "2006-10-26T00:45:13Z")

</div>

Heck. Why bother with tell in the first place? Why not call instance\_eval  
directly?

--Ken

> **···**
>
> On Thu, 26 Oct 2006 04:31:31 +0900, Gavin Kistner wrote:
> 
> > From: Morton Goldberg [mailto:m\_goldberg@ameritech.net]
> > 
> > > I'd rather pass in a block. Is there a way to do that? Something like:
> > > 
> > > \<pseud-code\>  
> > > module Kernel  
> > > &nbsp;&nbsp;&nbsp;&nbsp;def tell(obj, &to\_do)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# what goes here?  
> > > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > > end
> > > 
> > > tell Foo.new do  
> > > &nbsp;&nbsp;&nbsp;&nbsp;report  
> > > &nbsp;&nbsp;&nbsp;&nbsp;eat 'burger', 'fries'  
> > > &nbsp;&nbsp;&nbsp;&nbsp;drink 'beer'  
> > > &nbsp;&nbsp;&nbsp;&nbsp;be\_merry  
> > > end  
> > > \</pseud-code\>
> > 
> > def tell( obj, &to\_do )  
> > &nbsp;&nbsp;obj.instance\_eval( &to\_do )  
> > end
> 
> --  
> Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.  
> Department of Computer Science. Illinois Institute of Technology.  
> [http://www.iit.edu/~kbloom1/](http://www.iit.edu/~kbloom1/)  
> I've added a signing subkey to my GPG key. Please update your keyring.

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [25 October 2006 19:54 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/4 "2006-10-25T19:54:23Z")

</div>

Hi --

> > From: Morton Goldberg [mailto:m\_goldberg@ameritech.net]
> > 
> > > I'd rather pass in a block. Is there a way to do that? Something like:
> > > 
> > > \<pseud-code\>  
> > > module Kernel  
> > > &nbsp;&nbsp;&nbsp;def tell(obj, &to\_do)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# what goes here?  
> > > &nbsp;&nbsp;&nbsp;end  
> > > end
> > > 
> > > tell Foo.new do  
> > > &nbsp;&nbsp;&nbsp;report  
> > > &nbsp;&nbsp;&nbsp;eat 'burger', 'fries'  
> > > &nbsp;&nbsp;&nbsp;drink 'beer'  
> > > &nbsp;&nbsp;&nbsp;be\_merry  
> > > end  
> > > \</pseud-code\>
> > 
> > def tell( obj, &to\_do )  
> > obj.instance\_eval( &to\_do )  
> > end
> > 
> > class Foo  
> > def say\_hi  
> > &nbsp;&nbsp;&nbsp;p "Hi!"  
> > end  
> > end
> > 
> > tell Foo.new do  
> > say\_hi  
> > end  
> > #=\> "Hi!"
> 
> It's really that easy? Amazing! Ruby makes things so easy compared with the other languages I've used that I'm constantly inventing hard ways of doing what is too obvious for me to see.

It's easy, but it can also be a bit obfuscating. For example:

&nbsp;&nbsp;&nbsp;class C  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def initialize(thing)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@thing = thing  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def tell(&block)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval(&block)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;c = C.new("Hi")

&nbsp;&nbsp;&nbsp;@thing = "Hello"  
&nbsp;&nbsp;&nbsp;c.tell do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts @thing # Hi  
&nbsp;&nbsp;&nbsp;end

So you get some perhaps unwanted variable-shadowing, and similarly  
with method calls.

David

> **···**
>
> On Thu, 26 Oct 2006, Morton Goldberg wrote:
> 
> > On Oct 25, 2006, at 3:31 PM, Gavin Kistner wrote:
> 
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;David A. Black | dblack@wobblini.net  
> Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]  
> DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]  
> [1] [Ruby for Rails](http://www.manning.com/black) | [3] [http://www.rubypowerandlight.com](http://www.rubypowerandlight.com)  
> [2] [http://dablog.rubypal.com](http://dablog.rubypal.com) | [4] [http://www.rubycentral.org](http://www.rubycentral.org)

---

<div class="post-metadata">

**Author:** ![Daniel\_N1](https://avatars.discourse-cdn.com/v4/letter/d/df788c/32.png) [@Daniel\_N1](https://rubytalk.org/u/Daniel_N1)\
**Post date:** [26 October 2006 03:17 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/5 "2006-10-26T03:17:38Z")

</div>

My understanding of blocks is at best still very shakey, but is there a  
reason in all these that something like

def tell  
&nbsp;&nbsp;yield self  
end

would not have the desired effect.

Then with appropriate method missings etc you could call whatever you like  
in the block. If the drink and eat methods are already defined in the  
object, they would be called as appropriate.

so to use it.

obj = Foo.new  
obj.tell do  
&nbsp;&nbsp;eat 'burger', 'fries'  
&nbsp;&nbsp;drink 'beer'  
end

Is there a reason that this would not have the same effect as the  
instance\_eval methods?

---

<div class="post-metadata">

**Author:** ![Morton\_Goldberg](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@Morton\_Goldberg](https://rubytalk.org/u/Morton_Goldberg)\
**Post date:** [26 October 2006 05:29 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/6 "2006-10-26T05:29:03Z")

</div>

Syntactic sugar. I guess I have a sweet tooth.

Regards, Morton

> **···**
>
> On Oct 25, 2006, at 8:45 PM, Ken Bloom wrote:
> 
> > On Thu, 26 Oct 2006 04:31:31 +0900, Gavin Kistner wrote:
> > 
> > > From: Morton Goldberg [mailto:m\_goldberg@ameritech.net]
> > > 
> > > > I'd rather pass in a block. Is there a way to do that? Something like:
> > > > 
> > > > \<pseud-code\>  
> > > > module Kernel  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;def tell(obj, &to\_do)  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# what goes here?  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > > > end
> > > > 
> > > > tell Foo.new do  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;report  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;eat 'burger', 'fries'  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;drink 'beer'  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;be\_merry  
> > > > end  
> > > > \</pseud-code\>
> > > 
> > > def tell( obj, &to\_do )  
> > > &nbsp;&nbsp;obj.instance\_eval( &to\_do )  
> > > end
> > 
> > Heck. Why bother with tell in the first place? Why not call instance\_eval  
> > directly?

---

<div class="post-metadata">

**Author:** ![Morton\_Goldberg](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@Morton\_Goldberg](https://rubytalk.org/u/Morton_Goldberg)\
**Post date:** [25 October 2006 20:08 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/7 "2006-10-25T20:08:52Z")

</div>

I would expect that behavior and, in the situation I'm dealing with, I think it's an acceptable trade-off.

Regards, Morton

> **···**
>
> On Oct 25, 2006, at 3:54 PM, dblack@wobblini.net wrote:
> 
> > Hi --
> > 
> > On Thu, 26 Oct 2006, Morton Goldberg wrote:
> > 
> > > On Oct 25, 2006, at 3:31 PM, Gavin Kistner wrote:
> > > 
> > > > From: Morton Goldberg [mailto:m\_goldberg@ameritech.net]
> > > > 
> > > > > I'd rather pass in a block. Is there a way to do that? Something like:  
> > > > > \<pseud-code\>  
> > > > > module Kernel  
> > > > > &nbsp;&nbsp;&nbsp;def tell(obj, &to\_do)  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# what goes here?  
> > > > > &nbsp;&nbsp;&nbsp;end  
> > > > > end  
> > > > > tell Foo.new do  
> > > > > &nbsp;&nbsp;&nbsp;report  
> > > > > &nbsp;&nbsp;&nbsp;eat 'burger', 'fries'  
> > > > > &nbsp;&nbsp;&nbsp;drink 'beer'  
> > > > > &nbsp;&nbsp;&nbsp;be\_merry  
> > > > > end  
> > > > > \</pseud-code\>
> > > > 
> > > > def tell( obj, &to\_do )  
> > > > obj.instance\_eval( &to\_do )  
> > > > end  
> > > > class Foo  
> > > > def say\_hi  
> > > > &nbsp;&nbsp;&nbsp;p "Hi!"  
> > > > end  
> > > > end  
> > > > tell Foo.new do  
> > > > say\_hi  
> > > > end  
> > > > #=\> "Hi!"
> > > 
> > > It's really that easy? Amazing! Ruby makes things so easy compared with the other languages I've used that I'm constantly inventing hard ways of doing what is too obvious for me to see.
> > 
> > It's easy, but it can also be a bit obfuscating. For example:
> > 
> > &nbsp;&nbsp;class C  
> > &nbsp;&nbsp;&nbsp;&nbsp;def initialize(thing)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@thing = thing  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def tell(&block)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval(&block)  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;c = C.new("Hi")
> > 
> > &nbsp;&nbsp;@thing = "Hello"  
> > &nbsp;&nbsp;c.tell do  
> > &nbsp;&nbsp;&nbsp;&nbsp;puts @thing # Hi  
> > &nbsp;&nbsp;end
> > 
> > So you get some perhaps unwanted variable-shadowing, and similarly  
> > with method calls.

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [25 October 2006 20:09 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/8 "2006-10-25T20:09:12Z")

</div>

Greg Brown and I were playing around with a solution for the method call issue at RubyConf. Here's the code we came up with:

class C  
&nbsp;&nbsp;&nbsp;def initialize(thing)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@thing = thing  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;attr\_reader :thing

&nbsp;&nbsp;&nbsp;def tell(&block)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if block and block.arity == 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block[self]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval(&block)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end  
end

def thing; "Hello" end

c = C.new("Hi")

c.tell do  
&nbsp;&nbsp;&nbsp;thing # =\> "Hi"  
end

c.tell do |obj|  
&nbsp;&nbsp;&nbsp;thing # =\> "Hello"  
&nbsp;&nbsp;&nbsp;obj.thing # =\> "Hi"  
end

I know people frown on the instance\_eval() trick, but this seems to be less of a problem. You can just choose to use the variable when you need it.

Just a thought.

James Edward Gray II

> **···**
>
> On Oct 25, 2006, at 2:54 PM, dblack@wobblini.net wrote:
> 
> > It's easy, but it can also be a bit obfuscating. For example:
> > 
> > &nbsp;&nbsp;class C  
> > &nbsp;&nbsp;&nbsp;&nbsp;def initialize(thing)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@thing = thing  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def tell(&block)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval(&block)  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;c = C.new("Hi")
> > 
> > &nbsp;&nbsp;@thing = "Hello"  
> > &nbsp;&nbsp;c.tell do  
> > &nbsp;&nbsp;&nbsp;&nbsp;puts @thing # Hi  
> > &nbsp;&nbsp;end
> > 
> > So you get some perhaps unwanted variable-shadowing, and similarly  
> > with method calls.

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [26 October 2006 03:29 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/9 "2006-10-26T03:29:48Z")

</div>

Hi --

> **···**
>
> On Thu, 26 Oct 2006, Daniel N wrote:
> 
> > My understanding of blocks is at best still very shakey, but is there a  
> > reason in all these that something like
> > 
> > def tell  
> > yield self  
> > end
> > 
> > would not have the desired effect.
> > 
> > Then with appropriate method missings etc you could call whatever you like  
> > in the block. If the drink and eat methods are already defined in the  
> > object, they would be called as appropriate.
> > 
> > so to use it.
> > 
> > obj = Foo.new  
> > obj.tell do  
> > eat 'burger', 'fries'  
> > drink 'beer'  
> > end
> > 
> > Is there a reason that this would not have the same effect as the  
> > instance\_eval methods?
> 
> Yes: instance\_eval temporarily changes "self", and that means that  
> bareword method calls like eat and drink will be directed to the Foo  
> object. Otherwise, it's just like doing:
> 
> &nbsp;&nbsp;&nbsp;eat
> 
> in the middle of a program where you haven't defined an eat method.
> 
> David
> 
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;David A. Black | dblack@wobblini.net  
> Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]  
> DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]  
> [1] [Ruby for Rails](http://www.manning.com/black) | [3] [http://www.rubypowerandlight.com](http://www.rubypowerandlight.com)  
> [2] [http://dablog.rubypal.com](http://dablog.rubypal.com) | [4] [http://www.rubycentral.org](http://www.rubycentral.org)

---

<div class="post-metadata">

**Author:** ![Luc\_Juggery](https://avatars.discourse-cdn.com/v4/letter/l/ccd318/32.png) [@Luc\_Juggery](https://rubytalk.org/u/Luc_Juggery)\
**Post date:** [26 October 2006 09:44 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/10 "2006-10-26T09:44:08Z")

</div>

Hello All,

Sorry but I do not really understand the way instance\_eval is working  
in this sample:

def tell( obj, &to\_do )  
obj.instance\_eval( &to\_do )  
end

I'am new to Ruby and Metaprogramming and this method is still obscure to me.  
Can someone help ?  
Thanks a lot,

Luc

---

<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:** [25 October 2006 21:38 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/11 "2006-10-25T21:38:41Z")

</div>

James Edward Gray II wrote:

> > It's easy, but it can also be a bit obfuscating. For example:
> > 
> > &nbsp;&nbsp;class C  
> > &nbsp;&nbsp;&nbsp;&nbsp;def initialize(thing)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@thing = thing  
> > &nbsp;&nbsp;&nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;def tell(&block)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval(&block)  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;c = C.new("Hi")
> > 
> > &nbsp;&nbsp;@thing = "Hello"  
> > &nbsp;&nbsp;c.tell do  
> > &nbsp;&nbsp;&nbsp;&nbsp;puts @thing # Hi  
> > &nbsp;&nbsp;end
> > 
> > So you get some perhaps unwanted variable-shadowing, and similarly  
> > with method calls.
> 
> Greg Brown and I were playing around with a solution for the method call issue at RubyConf. Here's the code we came up with:
> 
> class C  
> &nbsp;&nbsp;def initialize(thing)  
> &nbsp;&nbsp;&nbsp;&nbsp;@thing = thing  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;attr\_reader :thing
> 
> &nbsp;&nbsp;def tell(&block)  
> &nbsp;&nbsp;&nbsp;&nbsp;if block and block.arity == 1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block[self]  
> &nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance\_eval(&block)  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end  
> end
> 
> def thing; "Hello" end
> 
> c = C.new("Hi")
> 
> c.tell do  
> &nbsp;&nbsp;thing # =\> "Hi"  
> end
> 
> c.tell do |obj|  
> &nbsp;&nbsp;thing # =\> "Hello"  
> &nbsp;&nbsp;obj.thing # =\> "Hi"  
> end
> 
> I know people frown on the instance\_eval() trick, but this seems to be less of a problem. You can just choose to use the variable when you need it.

I dunno... the presence of "|obj|" changes the semantics of the rest of the block. It's so easy to comment out the |obj| and then suddenly methods are handled in a surprising way:

c.tell do |obj|  
&nbsp;&nbsp;&nbsp;thing # =\> "Hello"  
end

c.tell do #|obj|  
&nbsp;&nbsp;&nbsp;thing # =\> "Hi"  
end

Visually, it doesn't look like anything important has changed.

Seems like a bug magnet.

> **···**
>
> > On Oct 25, 2006, at 2:54 PM, dblack@wobblini.net wrote:
> 
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

**Author:** ![Tim\_Pease](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@Tim\_Pease](https://rubytalk.org/u/Tim_Pease)\
**Post date:** [26 October 2006 03:32 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/12 "2006-10-26T03:32:44Z")

</div>

James, why do people frown upon instance\_eval? I know you cannot speak  
for all people, but what are the reasons to avoid it?

My only guess is that it would be slower than calling the block  
directly -- block[self] -- as you showed in the code example.

Thoughts?

TwP

> **···**
>
> On 10/25/06, James Edward Gray II \<james@grayproductions.net\> wrote:
> 
> > I know people frown on the instance\_eval() trick, but this seems to  
> > be less of a problem. You can just choose to use the variable when  
> > you need it.

---

<div class="post-metadata">

**Author:** ![Daniel\_N1](https://avatars.discourse-cdn.com/v4/letter/d/df788c/32.png) [@Daniel\_N1](https://rubytalk.org/u/Daniel_N1)\
**Post date:** [26 October 2006 03:38 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/13 "2006-10-26T03:38:33Z")

</div>

> Hi --
> 
> \> My understanding of blocks is at best still very shakey, but is there a  
> \> reason in all these that something like  
> \>  
> \> def tell  
> \> yield self  
> \> end  
> \>  
> \> would not have the desired effect.  
> \>  
> \> Then with appropriate method missings etc you could call whatever you  
> like  
> \> in the block. If the drink and eat methods are already defined in the  
> \> object, they would be called as appropriate.  
> \>  
> \> so to use it.  
> \>  
> \> obj = Foo.new  
> \> obj.tell do  
> \> eat 'burger', 'fries'  
> \> drink 'beer'  
> \> end  
> \>  
> \> Is there a reason that this would not have the same effect as the  
> \> instance\_eval methods?
> 
> Yes: instance\_eval temporarily changes "self", and that means that  
> bareword method calls like eat and drink will be directed to the Foo  
> object. Otherwise, it's just like doing:
> 
> &nbsp;&nbsp;&nbsp;eat
> 
> in the middle of a program where you haven't defined an eat method.

I'm a bit lost with that. I think I don't understand what is self inside  
the block. In the case of

def tell  
&nbsp;&nbsp;yield self  
end

> obj = Foo.new  
> obj.tell do  
> &nbsp;&nbsp;eat 'burger', 'fries'  
> &nbsp;&nbsp;drink 'beer'  
> end

What is self inside the block?

> **···**
>
> On 10/26/06, dblack@wobblini.net \<dblack@wobblini.net\> wrote:
> 
> > On Thu, 26 Oct 2006, Daniel N wrote:

---

<div class="post-metadata">

**Author:** ![HAL\_9000](https://avatars.discourse-cdn.com/v4/letter/h/90ced4/32.png) [@HAL\_9000](https://rubytalk.org/u/HAL_9000)\
**Post date:** [27 October 2006 00:04 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/14 "2006-10-27T00:04:29Z")

</div>

Luc Juggery wrote:

> Hello All,
> 
> Sorry but I do not really understand the way instance\_eval is working  
> in this sample:
> 
> def tell( obj, &to\_do )  
> obj.instance\_eval( &to\_do )  
> end
> 
> I'am new to Ruby and Metaprogramming and this method is still obscure to me.  
> Can someone help ?  
> Thanks a lot,

Look at it this way: The items inside the block are evaluated  
in the context of obj, rather than that of the tell method.

For example:

def tell( obj, &to\_do )  
&nbsp;&nbsp;&nbsp;p self  
&nbsp;&nbsp;&nbsp;obj.instance\_eval( &to\_do )  
end

If the to\_do block were to print self, it would be the  
same as obj (and \*different\* from what was printed before  
the instance\_eval).

HTH,  
Hal

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [26 October 2006 03:42 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/15 "2006-10-26T03:42:10Z")

</div>

the tk bindings work this way, and debugging can be frustrating:

&nbsp;&nbsp;&nbsp;harp:~ \> cat a.rb  
&nbsp;&nbsp;&nbsp;class C  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def a() :a end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def c() :c end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def m(&b) instance\_eval &b end  
&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;def b() :b end

&nbsp;&nbsp;&nbsp;p C.new.m{ mixed\_scope = [a, b, c] }

&nbsp;&nbsp;&nbsp;harp:~ \> ruby a.rb  
&nbsp;&nbsp;&nbsp;[:a, :b, :c]

certainly has it's application though....

-a

> **···**
>
> On Thu, 26 Oct 2006, Tim Pease wrote:
> 
> > On 10/25/06, James Edward Gray II \<james@grayproductions.net\> wrote:
> > 
> > > I know people frown on the instance\_eval() trick, but this seems to  
> > > be less of a problem. You can just choose to use the variable when  
> > > you need it.
> > 
> > James, why do people frown upon instance\_eval? I know you cannot speak  
> > for all people, but what are the reasons to avoid it?
> > 
> > My only guess is that it would be slower than calling the block  
> > directly -- block[self] -- as you showed in the code example.
> > 
> > Thoughts?
> 
> --  
> my religion is very simple. my religion is kindness. -- the dalai lama

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [26 October 2006 13:39 UTC](https://rubytalk.org/t/pass-block-instead-of-here-document/32315/16 "2006-10-26T13:39:12Z")

</div>

I have literally seen code like this:

&nbsp;&nbsp;&nbsp;must\_save = self  
&nbsp;&nbsp;&nbsp;whatever do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# use must\_save in here, even though self changed...  
&nbsp;&nbsp;&nbsp;end

This is a sign of instance\_eval() gone wrong, and Ara showed other issues.

Many take this as a sign that you should never instance\_eval() a block like this, but I think that's going a bit far. It's very handy in creating DSLs, for example.

James Edward Gray II

> **···**
>
> On Oct 25, 2006, at 10:32 PM, Tim Pease wrote:
> 
> > On 10/25/06, James Edward Gray II \<james@grayproductions.net\> wrote:
> > 
> > > I know people frown on the instance\_eval() trick, but this seems to  
> > > be less of a problem. You can just choose to use the variable when  
> > > you need it.
> > 
> > James, why do people frown upon instance\_eval? I know you cannot speak  
> > for all people, but what are the reasons to avoid it?
