# Eval? instance\_eval? hmm

**URL:** <https://www.ruby-forum.com/t/eval-instance-eval-hmm/169239>\
**Category:** Ruby\
**Created:** [June 1, 2009, 9:53am UTC](https://www.ruby-forum.com/t/eval-instance-eval-hmm/169239 "2009-06-01T09:53:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![steveybaby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c57346/32.png) [@steveybaby](https://www.ruby-forum.com/u/steveybaby)\
**Post date:** [June 1, 2009, 9:53am UTC](https://www.ruby-forum.com/t/eval-instance-eval-hmm/169239/1 "2009-06-01T09:53:30Z")

</div>

Hey ruby wizards. I got a question for you. I want to call a method on  
my object instance, with the method name specified by a string. I want  
to _pass in_ a hash to my method.

I tried:

myMethodName = “doSomeStuff”  
myObject.instance\_eval “#{myMethodName}(#{myHash})”

But it complained that it didn’t have a method named #{myHash.to\_s}.

So I tried myObject.instance\_eval { myMethodName(myHash) }

But it compalined that it didn’t have a method named “myMethodName”  
(which is obvious – the method I wanted to call is doSomeStuff).

I’m new to metaprogramming in ruby. What am I missing here?

Last thought: I guess I could assign a transient local var  
“@input\_hash”, then call the method which would use @input\_hash instead  
of requiring an input. That just seems a little ugly though. Any  
prettier solution?

-Steve

---

<div class="post-metadata">

**Author:** ![steveybaby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c57346/32.png) [@steveybaby](https://www.ruby-forum.com/u/steveybaby)\
**Post date:** [June 1, 2009, 10:47am UTC](https://www.ruby-forum.com/t/eval-instance-eval-hmm/169239/2 "2009-06-01T10:47:24Z")

</div>

2009/6/1 Steve H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> So I tried myObject.instance\_eval { myMethodName(myHash) }
> 
> But it compalined that it didn’t have a method named “myMethodName”  
> (which is obvious – the method I wanted to call is doSomeStuff).
> 
> I’m new to metaprogramming in ruby. What am I missing here?

myObject. **send** (myMethodName, myHash) is a more appropriate idiom for  
what  
you seem to be doing.

---

<div class="post-metadata">

**Author:** ![steveybaby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c57346/32.png) [@steveybaby](https://www.ruby-forum.com/u/steveybaby)\
**Post date:** [June 1, 2009, 10:52am UTC](https://www.ruby-forum.com/t/eval-instance-eval-hmm/169239/3 "2009-06-01T10:52:18Z")

</div>

Steve H. wrote:

> Hey ruby wizards. I got a question for you. I want to call a method on  
> my object instance, with the method name specified by a string. I want  
> to _pass in_ a hash to my method.
> 
> I tried:
> 
> myMethodName = “doSomeStuff”  
> myObject.instance\_eval “#{myMethodName}(#{myHash})”
> 
> But it complained that it didn’t have a method named #{myHash.to\_s}.

You can easily see what you’ve done wrong if you just use ‘puts’ instead  
of ‘myObject.instance\_eval’

Here’s it’s because you turned the hash into a string, and then inserted  
the string into your code, and then tried to run it.

irb(main):001:0\> myHash={“one”=\>1}  
=\> {“one”=\>1}  
irb(main):002:0\> def showit(x); puts “got #{x.inspect}”; end  
=\> nil  
irb(main):003:0\> myMethodName = “showit”  
=\> “showit”  
irb(main):004:0\> puts “#{myMethodName}(#{myHash})”  
showit(one1)  
=\> nil

Imagine what happens if you type “showit(one1)” at the command line.

What you needed was just to pass literally ‘myHash’ as the argument,  
whilst still interpolating the method name, i.e.

irb(main):005:0\> instance\_eval “#{myMethodName}(myHash)”  
got {“one”=\>1}  
=\> nil

However there are better ways to achieve this, without using the string  
version of eval. Probably all you want is this:

```
myObject.send(myMethodName, myHash)

```

> I’m new to metaprogramming in ruby. What am I missing here?

This isn’t metaprogramming (metaprogramming = programs which write  
programs). This is just dynamic method dispatch.

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![steveybaby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c57346/32.png) [@steveybaby](https://www.ruby-forum.com/u/steveybaby)\
**Post date:** [June 2, 2009, 2:12am UTC](https://www.ruby-forum.com/t/eval-instance-eval-hmm/169239/4 "2009-06-02T02:12:24Z")

</div>

James – perfect. Thanks!

Brian C. wrote:

> You can easily see what you’ve done wrong if you just use ‘puts’ instead  
> of ‘myObject.instance\_eval’
> 
> Here’s it’s because you turned the hash into a string, and then inserted  
> the string into your code, and then tried to run it.

Believe it or not, I did realize that. I just couldn’t find any docs  
showing me the proper usage of the string form of “instance\_eval” (ie,  
passing an argument).

> irb(main):005:0\> instance\_eval “#{myMethodName}(myHash)”  
> got {“one”=\>1}  
> =\> nil

See I thought about trying this, but didn’t even bother, as I expected  
it to fail. Anyway I’m glad to see it does indeed work like this.

> However there are better ways to achieve this, without using the string  
> version of eval. Probably all you want is this:
> 
> ```
> myObject.send(myMethodName, myHash)
> 
> ```

Yup. This works perfectly, thanks!!

> This isn’t metaprogramming (metaprogramming = programs which write  
> programs). This is just dynamic method dispatch.

Hah yeah I realize that now… cut me some slack, it was ~1:30am my  
time and the wife was harassing me to come to bed! 😉  
Anyway, as you may have guessed, I’m new to Ruby in general. Only been  
working with the language for about 3 months. So far I’m loooooving it.  
🙂

Thanks for the helpful replies! I got it working exactly how I wanted.

-Steve

---

<div class="post-metadata">

**Author:** ![steveybaby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/c57346/32.png) [@steveybaby](https://www.ruby-forum.com/u/steveybaby)\
**Post date:** [June 2, 2009, 9:31am UTC](https://www.ruby-forum.com/t/eval-instance-eval-hmm/169239/5 "2009-06-02T09:31:41Z")

</div>

Steve H. wrote:

> > Here’s it’s because you turned the hash into a string, and then inserted  
> > the string into your code, and then tried to run it.
> 
> Believe it or not, I did realize that. I just couldn’t find any docs  
> showing me the proper usage of the string form of “instance\_eval” (ie,  
> passing an argument).

I wouldn’t expect there to be any. eval or instance\_eval with a string  
just parses and runs Ruby code, so the proper usage is “just put some  
valid Ruby code in there” 🙂

That’s why it’s useful to use puts for debugging - you can see at a  
glance whether that code would be valid or not, if you had just inserted  
it into your program at that point.

> Thanks for the helpful replies! I got it working exactly how I wanted.

No problem, glad it’s all making sense.

Cheers,

Brian.
