# Instance eval in 1.8 and 1.9

**URL:** <https://www.ruby-forum.com/t/instance-eval-in-1-8-and-1-9/191752>\
**Category:** Ruby\
**Created:** [July 17, 2010, 5:25pm UTC](https://www.ruby-forum.com/t/instance-eval-in-1-8-and-1-9/191752 "2010-07-17T17:25:37Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [July 17, 2010, 5:25pm UTC](https://www.ruby-forum.com/t/instance-eval-in-1-8-and-1-9/191752/1 "2010-07-17T17:25:37Z")

</div>

Hi,

Porting a program from 1.8 to 1.9, I hit a stumbling block in the use  
of instance\_eval.

The following code works in 1.8 but not 1.9. instance\_eval in 1.9  
does not allow you to use a lambda as a block. The solution is to use  
a proc instead. I understand that lambdas are like methods and procs  
are like blocks, but what gets me is the incredibly unhelpful error  
message.

Anyway, the code (can also see it at [http://gist.github.com/479572](http://gist.github.com/479572) )

class InstanceEval  
def initialize(x)  
@block = x  
@context = Object.new  
end

```
def run
  code = @block
  result = @object.instance_eval(&code)
  "* run --> #{result.inspect}"
end

```

end

p = proc { 😛 }  
l = lambda { :l } # (line 16 – for the error message  
below)

puts InstanceEval.new(p).run  
puts InstanceEval.new(l).run

The output in 1.8:

- run → 😛
- run → :l

The output in 1.9:

- run → 😛  
code.rb:16:in `block in <main>': wrong number of arguments (1 for 0) (ArgumentError) from code.rb:10:in `instance\_eval’  
from code.rb:10:in `run' from code.rb:19:in `’

To what method have I passed one argument where zero arguments were  
expected?

Is the average Ruby programmer supposed to know that instance\_eval  
can’t take a lambda in Ruby 1.9? Perhaps it should say so in the  
documentation. ([http://bit.ly/96HBeb](http://bit.ly/96HBeb))

Is there a good reason ( instance\_eval &lambda\_object ) can’t work?

Thanks for any light you can shed on it.

Gavin

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [July 17, 2010, 6:09pm UTC](https://www.ruby-forum.com/t/instance-eval-in-1-8-and-1-9/191752/2 "2010-07-17T18:09:31Z")

</div>

On Saturday 17 July 2010, Gavin S. wrote:

> |  
> | result = @object.instance\_eval(&code)  
> |  
> |(ArgumentError)  
> |  
> |Is there a good reason ( instance\_eval &lambda\_object ) can’t work?  
> |  
> |Thanks for any light you can shed on it.  
> |  
> |Gavin

Your code runs without errors for me with ruby 1.9.1-p376.

Stefano

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [July 17, 2010, 8:31pm UTC](https://www.ruby-forum.com/t/instance-eval-in-1-8-and-1-9/191752/3 "2010-07-17T20:31:46Z")

</div>

On 7/17/10, Gavin S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > Your code runs without errors for me with ruby 1.9.1-p376.
> > 
> > Stefano
> 
> Thanks for testing it. I should have specified my version, of course:
> 
> ruby 1.9.2dev (2010-07-02 revision 28524) [i386-cygwin]

It seems like this could be a regression. The error message at the  
very least is a bug. I suggest you file a bug report for this.

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [July 19, 2010, 3:06pm UTC](https://www.ruby-forum.com/t/instance-eval-in-1-8-and-1-9/191752/4 "2010-07-19T15:06:03Z")

</div>

Caleb C. wrote:

> On 7/17/10, Gavin S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > > Your code runs without errors for me with ruby 1.9.1-p376.
> > > 
> > > Stefano
> > 
> > Thanks for testing it. I should have specified my version, of course:
> > 
> > ruby 1.9.2dev (2010-07-02 revision 28524) [i386-cygwin]
> 
> It seems like this could be a regression.

Seconded. The program works OK for me with ruby 1.9.2dev (2009-07-18  
trunk 24186) [i686-linux]

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [July 19, 2010, 4:32pm UTC](https://www.ruby-forum.com/t/instance-eval-in-1-8-and-1-9/191752/5 "2010-07-19T16:32:10Z")

</div>

On 7/19/10, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > It seems like this could be a regression.
> 
> Seconded. The program works OK for me with ruby 1.9.2dev (2009-07-18  
> trunk 24186) [i686-linux]

Nobu says this is not a bug, and his explanation makes perfect sense  
to me, now that I understand it. instance\_eval passes self as a  
parameter to the block in 1.8 and 1.9.2 but didn’t in 1.9.1. Also,  
lambda panics if it doesn’t receive the expected number of params,  
whereas proc does not.

See ruby-core:31336

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [July 19, 2010, 4:57pm UTC](https://www.ruby-forum.com/t/instance-eval-in-1-8-and-1-9/191752/6 "2010-07-19T16:57:21Z")

</div>

> > It seems like this could be a regression.
> 
> Seconded. The program works OK for me with ruby 1.9.2dev (2009-07-18  
> trunk 24186) [i686-linux]

Data so far:

- works on 1.9.1-p376 [Caleb, Gavin]
- works on 1.9.2dev (2009-07-18) [Brian]
- doesn’t work on 1.9.2dev (2010-07-02) [Gavin]

That agrees with Nobu’s comment on ruby-core (which I should have  
relayed here earlier, sorry):

```
No, it not the point. Now instance_eval yields the self.

```

This code (to boil the problematic case down) fails…

```
code = lambda { 42 }
instance_eval &code

```

…because instance\_eval passes ‘self’ as a parameter to the block.  
Lambdas are fussy about parameters being accounted for, hence the  
ArgumentError. Procs are not fussy about parameters, so replace  
‘lambda’ with ‘proc’ in the above code and it works.

For that matter, _this_ works too:

```
code = lambda { |s| 42 }
instance_eval &code

```

From what I gather:

- in 1.8.x, instance\_eval passed self but it was an undocumented  
feature  
and lambdas weren’t fussy so it didn’t matter
- in 1.9.1 instance\_eval stopped passing self (don’t know whether that  
change  
was intentional)
- heading towards 1.9.2 it started passing self again, from about  
December 2009

For a (still?)-undocumented feature, the message “ArgumentError: 0 for  
1” is not very helpful.

Gavin

---

<div class="post-metadata">

**Author:** ![gavin\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/839c29/32.png) [@gavin\_s](https://www.ruby-forum.com/u/gavin_s)\
**Post date:** [July 17, 2010, 7:09pm UTC](https://www.ruby-forum.com/t/instance-eval-in-1-8-and-1-9/191752/7 "2010-07-17T19:09:49Z")

</div>

> Your code runs without errors for me with ruby 1.9.1-p376.
> 
> Stefano

Thanks for testing it. I should have specified my version, of course:

ruby 1.9.2dev (2010-07-02 revision 28524) [i386-cygwin]

Gavin
