# Local variables can't be accessed from outside, right?

**URL:** <https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555>\
**Category:** Ruby\
**Created:** [November 28, 2009, 6:56am UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555 "2009-11-28T06:56:40Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![dezrtdude](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/f4b2a3/32.png) [@dezrtdude](https://www.ruby-forum.com/u/dezrtdude)\
**Post date:** [November 28, 2009, 6:56am UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555/1 "2009-11-28T06:56:40Z")

</div>

Hi, I’ve been trying to figure out metaprogramming and I’ve mostly got  
it figured out, but in doing so I ran across this example:

class A  
def initialize  
@a = 11  
@@a = 22  
a = 33  
end  
@a = 1  
@@a = 2  
a = 3  
end

This was given as a posed question (can you access all the variables)  
and a particular order of the output was given (specifically, 1 2 3 11  
22 33). Getting at the instance variables, and even the class variables  
doesn’t seem that hard to me. But it seems to me there’s no way to get  
at the local variable a’s. The way it was asked makes me think it might  
be possible, but I’m reasonably sure it isn’t.

However, I’m fairly new to Ruby and just wrapping my mind around the  
metaprogramming ideas and realize I could easily be missing something.

I think a trick like puts A.new would be a lame solution, as would  
finding it somehow in memory after the class definition end statement  
(though that might be interesting to know if Ruby can do that).

---

<div class="post-metadata">

**Author:** ![dezrtdude](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/f4b2a3/32.png) [@dezrtdude](https://www.ruby-forum.com/u/dezrtdude)\
**Post date:** [November 28, 2009, 7:30am UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555/2 "2009-11-28T07:30:29Z")

</div>

Michael W. wrote:

> Hi, I’ve been trying to figure out metaprogramming and I’ve mostly got  
> it figured out, but in doing so I ran across this example:
> 
> class A  
> def initialize  
> @a = 11  
> @@a = 22  
> a = 33  
> end  
> @a = 1  
> @@a = 2  
> a = 3  
> end
> 
> This was given as a posed question (can you access all the variables)  
> and a particular order of the output was given (specifically, 1 2 3 11  
> 22 33). Getting at the instance variables, and even the class variables  
> doesn’t seem that hard to me. But it seems to me there’s no way to get  
> at the local variable a’s. The way it was asked makes me think it might  
> be possible, but I’m reasonably sure it isn’t.
> 
> However, I’m fairly new to Ruby and just wrapping my mind around the  
> metaprogramming ideas and realize I could easily be missing something.
> 
> I think a trick like puts A.new would be a lame solution,

Well, it would be the only solution to a lame question. 🙂

> finding it somehow in memory after the class definition end statement  
> (though that might be interesting to know if Ruby can do that).

Sort of. Remember, a class definition is executable code. Does that  
give you an idea? It should.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![dezrtdude](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/f4b2a3/32.png) [@dezrtdude](https://www.ruby-forum.com/u/dezrtdude)\
**Post date:** [November 28, 2009, 7:47am UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555/3 "2009-11-28T07:47:17Z")

</div>

On Friday 27 November 2009 11:56:43 pm Michael W. wrote:

> @@a = 2  
> a = 3  
> end
> 
> This was given as a posed question (can you access all the variables)  
> and a particular order of the output was given (specifically, 1 2 3 11  
> 22 33).

> I think a trick like puts A.new would be a lame solution,

That actually wouldn’t work, though I can see why you think it’d be  
lame.

Anyway, as far as I know, there are only a few ways to access a local  
variable:

You could define a= – for example,

def a=(value)  
puts a  
end

The problem is, I can’t actually get this to work reliably. It really  
seems  
like assignment of this kind would only work if you did

self.a = 33

So, with that discarded, I don’t think it’s possible to get access to  
these  
local variables with the class as written, at least not cleanly. You  
could  
probably figure out (programatically) where the class is defined, and  
then  
parse the source.

Other than that, the only way I know of getting at local variables is  
through  
the binding object, which you’d have to get either from inside the code,  
or  
from something called from that code – but that class doesn’t seem to  
call  
any methods from anywhere you care about, so that doesn’t work.

---

<div class="post-metadata">

**Author:** ![dezrtdude](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/f4b2a3/32.png) [@dezrtdude](https://www.ruby-forum.com/u/dezrtdude)\
**Post date:** [November 28, 2009, 12:08pm UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555/4 "2009-11-28T12:08:17Z")

</div>

class\_local\_a = class A  
def initialize  
@a = 11  
@@a = 22  
a = 33  
end  
@a = 1  
@@a = 2  
a = 3  
end

p A.instance\_variable\_get(:@a) #ok

p A.class\_variable\_get(:@@a) if RUBY\_VERSION \> ‘1.9’  
class A; p @@a end if RUBY\_VERSION \< ‘1.9’

# a little tricky, sure

p class\_local\_a

p A.new.instance\_variable\_get(:@a)

p A.class\_variable\_get(:@@a) if RUBY\_VERSION \> ‘1.9’  
class A; p @@a end if RUBY\_VERSION \< ‘1.9’

p A.new.method(:initialize).call

I didn’t find other way to get the result of class A … end like a if  
or  
case result.  
Very weared a class’ instance variable(1)  
Does it have any interest?

2009/11/28 David M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![dezrtdude](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/f4b2a3/32.png) [@dezrtdude](https://www.ruby-forum.com/u/dezrtdude)\
**Post date:** [November 28, 2009, 7:15pm UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555/5 "2009-11-28T19:15:22Z")

</div>

Benoit D. wrote:

> I didn’t find other way to get the result of class A … end like a if  
> or  
> case result.  
> Very weared a class’ instance variable(1)  
> Does it have any interest?

No, it’s just an example for learning about metaprogramming. Which is  
why it seems strange; the local variables can only be ‘accessed’ because  
they happen to be return values.

I did learn something I didn’t know, however :

class A  
puts “Local variables: #{local\_variables}”  
puts “Instance variables: #{instance\_variables}”  
a = 5  
@a = 6  
puts “Local variables: #{local\_variables}”  
puts “Instance variables: #{instance\_variables}”  
end

Local variables: a  
Instance variables:  
Local variables: a  
Instance variables: @a

So local variables exist in some ethereal void after the code is scanned  
but before they can be used; not so with instance variables. That makes  
some sense. But this also lets you do this eval weirdness.

class B  
puts “#{local\_variables.first} = #{eval(local\_variables.first)},  
which is a #{eval(local\_variables.first).class}”  
eval(local\_variables.first + “=2”)  
puts “#{local\_variables.first} = #{eval(local\_variables.first)},  
which is a #{eval(local\_variables.first).class}”

```
puts #{a} if a #=> NameError: undefined local variable or method 

```

‘a’ for B:Class  
a = 4  
puts “#{local\_variables.first} = #{eval(local\_variables.first)},  
which is a #{eval(local\_variables.first).class}”  
end

With the error commented out, this gives:  
a = , which is a NilClass  
a = 2, which is a Fixnum  
a = 4, which is a Fixnum

---

<div class="post-metadata">

**Author:** ![dezrtdude](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/f4b2a3/32.png) [@dezrtdude](https://www.ruby-forum.com/u/dezrtdude)\
**Post date:** [November 28, 2009, 9:11pm UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555/6 "2009-11-28T21:11:58Z")

</div>

On Sat, Nov 28, 2009 at 2:30 PM, pharrington [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> was defined)  
> Actually, for MRI, at compile time a local gets assigned an index  
> which is used to dereference an element of an array of local variables  
> pointed to by a structure called SCOPE there is a stack of these  
> scopes which grows and shrinks as methods and blocks are called and  
> returned…

The actual local variables need to be unique for each method  
invocation or block evaluation.

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![dezrtdude](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/f4b2a3/32.png) [@dezrtdude](https://www.ruby-forum.com/u/dezrtdude)\
**Post date:** [November 28, 2009, 8:30pm UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555/7 "2009-11-28T20:30:25Z")

</div>

On Nov 28, 1:15 pm, Michael W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> they happen to be return values.  
> end
> 
> Local variables: a  
> Instance variables:  
> Local variables: a  
> Instance variables: @a
> 
> So local variables exist in some ethereal void after the code is scanned  
> but before they can be used; not so with instance variables. That makes  
> some sense. But this also lets you do this eval weirdness.

From what I understand, this is because local variables are created  
when code is _parsed_, not actually run (as method resolution would be  
even more painful if the interpreter had to first search the object  
tree for a particular instance method every time a new local variable  
was defined)

---

<div class="post-metadata">

**Author:** ![dezrtdude](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/f4b2a3/32.png) [@dezrtdude](https://www.ruby-forum.com/u/dezrtdude)\
**Post date:** [November 28, 2009, 9:47pm UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555/8 "2009-11-28T21:47:40Z")

</div>

p\> From what I understand, this is because local variables are created  
p\> when code is _parsed_, not actually run (as method resolution would  
be  
p\> even more painful if the interpreter had to first search the object  
p\> tree for a particular instance method every time a new local variable  
p\> was defined)

Ah! So local variables are created when parsed but instance and class  
variables are created at execution!

I hope that’s right because a lightbulb just turned on.

---

<div class="post-metadata">

**Author:** ![dezrtdude](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/f4b2a3/32.png) [@dezrtdude](https://www.ruby-forum.com/u/dezrtdude)\
**Post date:** [November 28, 2009, 10:00pm UTC](https://www.ruby-forum.com/t/local-variables-cant-be-accessed-from-outside-right/179555/9 "2009-11-28T22:00:32Z")

</div>

On Nov 28, 3:46 pm, Ralph S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> p\> From what I understand, this is because local variables are created  
> p\> when code is _parsed_, not actually run (as method resolution would be  
> p\> even more painful if the interpreter had to first search the object  
> p\> tree for a particular instance method every time a new local variable  
> p\> was defined)
> 
> Ah! So local variables are created when parsed but instance and class  
> variables are created at execution!
> 
> I hope that’s right because a lightbulb just turned on.

Well its not exactly right (as Rick DeNatale explained) buts its a  
simple way to picture what goes on.
