# Can I tighten this up with block or eval?

**URL:** <https://www.ruby-forum.com/t/can-i-tighten-this-up-with-block-or-eval/162914>\
**Category:** Ruby\
**Created:** [March 15, 2009, 6:21pm UTC](https://www.ruby-forum.com/t/can-i-tighten-this-up-with-block-or-eval/162914 "2009-03-15T18:21:06Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![matt\_neuburg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4af34b/32.png) [@matt\_neuburg](https://www.ruby-forum.com/u/matt_neuburg)\
**Post date:** [March 15, 2009, 6:21pm UTC](https://www.ruby-forum.com/t/can-i-tighten-this-up-with-block-or-eval/162914/1 "2009-03-15T18:21:06Z")

</div>

I have here a class called ClassMaker whose greeter method returns an  
instance of anonymous class containing a hello method:

class ClassMaker  
def initialize(s); @howdy = s; end  
def greeter  
c = Class.new do  
def initialize(s); @hello = s; end  
def hello  
puts @hello # this is the nub of the matter  
end  
end  
c.new(@howdy)  
end  
end

ClassMaker.new(“gday”).greeter.hello

I would like the anonymous class’s hello method to access whatever the  
value of my ClassMaker instance’s @howdy ivar may be at the moment  
greeter is called. I am presently doing this, as you can see, by giving  
the anonymous class an initialize method and passing the @howdy ivar’s  
value into an ivar of the anonymous class’s instance.

This works but seems heavy-handed. I feel I should be able to do it  
without the anonymous class having any initialize method at all. The  
whole situation has “closure” written all over it. So I tried to define  
the hello method to accomplish the same thing using evals and blocks and  
other tricky stuff, and became hopelessly confused. Could someone  
straighten me out? Thx - m.

---

<div class="post-metadata">

**Author:** ![matt\_neuburg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4af34b/32.png) [@matt\_neuburg](https://www.ruby-forum.com/u/matt_neuburg)\
**Post date:** [March 15, 2009, 6:49pm UTC](https://www.ruby-forum.com/t/can-i-tighten-this-up-with-block-or-eval/162914/2 "2009-03-15T18:49:16Z")

</div>

On Mar 15, 2009, at 1:17 PM, matt neuburg wrote:

> This works but seems heavy-handed. I feel I should be able to do it  
> without the anonymous class having any initialize method at all. The  
> whole situation has “closure” written all over it. So I tried to  
> define  
> the hello method to accomplish the same thing using evals and blocks  
> and  
> other tricky stuff, and became hopelessly confused. Could someone  
> straighten me out? Thx - m.

Here is one possibility. Note, I changed ClassMaker to a module  
since it is really just a factory for creating classes and doesn’t  
really need to create intermediate instances of ClassMaker to  
accomplish your goal.

module ClassMaker  
def self.greeter(greeting)  
Class.new do  
define\_method :hello do  
puts greeting # this is the nub of the matter  
end  
end  
end  
end

ClassMaker.greeter(“gday”).new.hello  
ClassMaker.greeter(“aloha”).new.hello

Gary W.

---

<div class="post-metadata">

**Author:** ![matt\_neuburg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4af34b/32.png) [@matt\_neuburg](https://www.ruby-forum.com/u/matt_neuburg)\
**Post date:** [March 15, 2009, 7:31pm UTC](https://www.ruby-forum.com/t/can-i-tighten-this-up-with-block-or-eval/162914/3 "2009-03-15T19:31:03Z")

</div>

Gary W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Here is one possibility. Note, I changed ClassMaker to a module  
> end  
> end  
> end  
> ClassMaker.greeter(“gday”).new.hello

Actually, I have to keep the architecture I’ve got - greeter is going to  
be called without a parameter, that’s just how it is. (The problem as I  
posed it is just a schematic reduction of a vast existing architecture  
that does something else entirely.)

However, your solution shows me exactly the trick I was missing: I need  
to turn @howdy into a local so that a block can see it:

class ClassMaker  
def initialize(s); @howdy = s; end  
def greeter  
greeting = @howdy # the magic step!  
Class.new do  
define\_method :hello do  
puts greeting  
end  
end.new  
end  
end  
ClassMaker.new(“gday”).greeter.hello

Thanks! It’s nice to stop banging myself over the head with a hammer…  
🙂

m.
