# Eval needs explicit self for accessor methods?

**URL:** <https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604>\
**Category:** Ruby\
**Created:** [April 1, 2006, 5:10pm UTC](https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604 "2006-04-01T17:10:43Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tfdj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dec6dc/32.png) [@tfdj](https://www.ruby-forum.com/u/tfdj)\
**Post date:** [April 1, 2006, 5:10pm UTC](https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604/1 "2006-04-01T17:10:43Z")

</div>

hi all!

i encountered a strange problem with eval. please see the following  
test case:

require ‘test/unit’

class TestContext

def eval\_in\_context( ruby\_code )  
instance\_eval ruby\_code  
end

def toast  
@toast  
end

def toast=( val )  
@toast = val  
end

end

class TestMetaEval \< Test::Unit::TestCase

def test\_toast  
tc = TestContext.new  
tc.toast = ‘yes’

```
assert_equal 'yes', tc.toast
assert_equal 'yes', tc.eval_in_context( "toast" )

# These two lines - using explicit self - work as expected:
assert_equal 'maybe', tc.eval_in_context( "self.toast = 'maybe'" )
assert_equal 'maybe', tc.toast

# What is happening here:
assert_equal 'no', tc.eval_in_context( "toast = 'no'" )

# Why does the next test fail?
# What did the previous line set? A local variable?

# tc.toast returns 'maybe' here instead of the expected 'no':
assert_equal 'no', tc.toast

```

end

end

why is the ‘toast=(val)’ method not visible in eval unless i  
explicitly use “self.toast = …”?

what is it i don’t understand about ruby scoping? 😕

any help really appreciated!

cheers,

daniel

---

<div class="post-metadata">

**Author:** ![tfdj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dec6dc/32.png) [@tfdj](https://www.ruby-forum.com/u/tfdj)\
**Post date:** [April 1, 2006, 5:29pm UTC](https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604/2 "2006-04-01T17:29:59Z")

</div>

It really has nothing to do with eval, your just setting a local  
variable.

An unfortuate side effect of the setter notation is that it conflicts  
with local var setting. Local var setting wins out, so you have to use  
self as the reciever in order to tell ruby you mean the setter method.

T.

---

<div class="post-metadata">

**Author:** ![tfdj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dec6dc/32.png) [@tfdj](https://www.ruby-forum.com/u/tfdj)\
**Post date:** [April 1, 2006, 5:43pm UTC](https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604/3 "2006-04-01T17:43:25Z")

</div>

Of course! Thank you! Sorry for the dumb question. Makes perfect sense  
now…

dl

---

<div class="post-metadata">

**Author:** ![tfdj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dec6dc/32.png) [@tfdj](https://www.ruby-forum.com/u/tfdj)\
**Post date:** [April 1, 2006, 9:16pm UTC](https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604/4 "2006-04-01T21:16:39Z")

</div>

Trans wrote:

> It really has nothing to do with eval, your just setting a local  
> variable.
> 
> An unfortuate side effect of the setter notation is that it conflicts  
> with local var setting. Local var setting wins out, so you have to use  
> self as the reciever in order to tell ruby you mean the setter method.
> 
> T.

Since you bring this up, there are a few more cases where implicit  
locals  
declaration causes unexpected behavior (if new to ruby that is):

x = 10  
(1…10).each { |i| x = x + i } # x == 65  
x = 10  
(1…10).each { |i| x = i } # x == 10

So if you’re assigning x to itself in some way, it recognizes x in the  
enclosing scope, else it creates a new local. That’s kind of a  
confusing rule.  
Also, what if I wanted the first example to create a local? How do  
I refer  
to the toplevel `x` in the second?

I’d really like to see explicit locals declarations in Ruby, and this  
would all  
be solved by simply introducing `var` or `local`, as in `var x = 10`.  
Even if  
it was only optional, and invoked with -strict-locals, I think many  
people  
would be happy. Maybe I’ll download the source and hack away to test it  
🙂

Mike

---

<div class="post-metadata">

**Author:** ![tfdj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dec6dc/32.png) [@tfdj](https://www.ruby-forum.com/u/tfdj)\
**Post date:** [April 1, 2006, 9:56pm UTC](https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604/5 "2006-04-01T21:56:28Z")

</div>

On Apr 1, 2006, at 2:13 PM, Mike A. wrote:

> So if you’re assigning x to itself in some way, it recognizes x in  
> the enclosing scope, else it creates a new local. That’s kind of a  
> confusing rule. Also, what if I wanted the first example to  
> create a local? How do I refer to the toplevel `x` in the second?

The ‘x’ in each of those blocks references the local variable ‘x’  
defined outside the block.  
In neither case is a new local variable ‘x’ created within the  
block. In both cases a new  
local variable ‘i’ is created within the blocks and is only visible  
within the individual block.

Here are the rules I use to understand local variable scope and blocks:

1. Local variables _created_ outside a block are visible inside the  
block.

2. Local variables _created_ inside a block are _not_ visible outside  
the block.

3. Block arguments behave like _local_ variables _not_ formal  
(method) arguments.

If you combine 1 and 2 you see that block scope is sort of a one-way  
barrier. Code inside the block can see variables created outside the  
block but not the other way around.

The third rule is the one that throws everyone because most  
programmers tend to think of block arguments as formal arguments that  
shadow any similarly named variables outside the block but this is  
incorrect (in Ruby). Block arguments behave like _local_ variables  
so if a block argument has the same name as a variable in the  
enclosing scope then a new local variable is _not_ created. On the  
other hand if there is no local variable in the enclosing scope with  
the same name then a new local variable _is_ created and is only  
visible within the block (rule 2).

I believe it is rule 3) that Matz is considering changing for Ruby 2.0

Gary W.

---

<div class="post-metadata">

**Author:** ![tfdj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dec6dc/32.png) [@tfdj](https://www.ruby-forum.com/u/tfdj)\
**Post date:** [April 1, 2006, 10:33pm UTC](https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604/6 "2006-04-01T22:33:16Z")

</div>

On Apr 1, 2006, at 2:53 PM, removed\_email\_address@domain.invalid wrote:

> (method) arguments.  
> Good list!

---

<div class="post-metadata">

**Author:** ![tfdj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dec6dc/32.png) [@tfdj](https://www.ruby-forum.com/u/tfdj)\
**Post date:** [April 1, 2006, 11:55pm UTC](https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604/7 "2006-04-01T23:55:59Z")

</div>

removed\_email\_address@domain.invalid wrote:

> > 
> 
> within the individual block.
> 
> new local variable is _not_ created. On the other hand if there is no  
> local variable in the enclosing scope with the same name then a new  
> local variable _is_ created and is only visible within the block (rule 2).
> 
> I believe it is rule 3) that Matz is considering changing for Ruby 2.0

Changing the hiding characteristics of formal arguments sounds like a  
good  
idea, but there’s still a big problem of not being able to declare  
locals. For  
example, given the following:

def test()  
a = 2  
Proc.new { Proc.new { a = 10 }.call() }.call()  
puts a  
end

test() =\> 10

Lexical closure are a very nice thing, but if I think I’m creating a  
local when  
in fact I’m modifying some value in the enclosing scope, then that’s  
bad. I  
think shadowing a parameters is a lot less dangerous, and a warning can  
be  
printed when that happens. So the above would look like this:

Proc.new { Proc.new { var a = 10 }.call() }.call()

Mike

---

<div class="post-metadata">

**Author:** ![tfdj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dec6dc/32.png) [@tfdj](https://www.ruby-forum.com/u/tfdj)\
**Post date:** [April 2, 2006, 4:51pm UTC](https://www.ruby-forum.com/t/eval-needs-explicit-self-for-accessor-methods/56604/8 "2006-04-02T16:51:18Z")

</div>

Mike A. schrieb:

> confusing rule. Also, what if I wanted the first example to create a  
> local? How do I refer to the toplevel `x` in the second?

Mike, you’re accessing the toplevel “x” in both cases:

x = nil  
(1…10).each { |i| x = i } # x == 10

Regards,  
Pit
