# How to access to local variables in enclosing scopes?

**URL:** <https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930>\
**Category:** ruby-talk\
**Created:** [31 October 2008 17:43 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930 "2008-10-31T17:43:58Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yuh-Ruey\_Chen](https://avatars.discourse-cdn.com/v4/letter/y/57b2e6/32.png) [@Yuh-Ruey\_Chen](https://rubytalk.org/u/Yuh-Ruey_Chen)\
**Post date:** [31 October 2008 17:43 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/1 "2008-10-31T17:43:58Z")

</div>

I'm familiar with other popular scripting languages (JS and Python),  
and I'm struggling to figure out Ruby's (inanely) complex scoping  
mechanisms.

My questions are within the following example:

x = 10

def foo  
&nbsp;&nbsp;# how to access x from here?  
end

class Klass  
&nbsp;&nbsp;# how to access x from here?  
&nbsp;&nbsp;def bar  
&nbsp;&nbsp;&nbsp;&nbsp;# how to access x from here?  
&nbsp;&nbsp;end  
end

lambda { x } # I can access x here but why not in foo or Klass or bar?

I sincerely hope I'm missing something here. To me, the inability to  
access local variables in an enclosing scope is very counter-  
intuitive. I thought Ruby was supposed to be elegant? At the very  
least, I expect some sort of "nonlocal" statement similar to Python,  
e.g.

def foo  
&nbsp;&nbsp;nonlocal x  
&nbsp;&nbsp;# I can access x in enclosing scope now  
end

And no, I don't want to have to use global variables - that would just  
be pollution and would be incredibly unwieldy in large projects.  
Frankly, if there was a way to access local variables in enclosing  
scopes, there wouldn't even need to be a special global variable  
concept.

---

<div class="post-metadata">

**Author:** ![David\_A\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_A\_Black1](https://rubytalk.org/u/David_A_Black1)\
**Post date:** [31 October 2008 17:55 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/2 "2008-10-31T17:55:11Z")

</div>

Hi --

> I'm familiar with other popular scripting languages (JS and Python),  
> and I'm struggling to figure out Ruby's (inanely) complex scoping  
> mechanisms.

The rules are pretty simple. The def, class, and module keywords start  
new local scopes. That's most of it.

> My questions are within the following example:
> 
> x = 10
> 
> def foo  
> &nbsp;&nbsp;# how to access x from here?
> 
> end
> 
> class Klass  
> &nbsp;&nbsp;# how to access x from here?  
> &nbsp;&nbsp;def bar  
> &nbsp;&nbsp;&nbsp;&nbsp;# how to access x from here?  
> &nbsp;&nbsp;end  
> end
> 
> lambda { x } # I can access x here but why not in foo or Klass or bar?

I'm not sure what you mean by "why". Every language has scoping rules.  
Ruby's rules include provision for closures, in that code blocks do  
not start a new local scope and can be used as the bodies of anonymous  
function objects.

There's no moral imperative, one way or the other. You're just  
encountering and learning how Ruby handles these things. Relax 🙂

> I sincerely hope I'm missing something here. To me, the inability to  
> access local variables in an enclosing scope is very counter-  
> intuitive. I thought Ruby was supposed to be elegant? At the very  
> least, I expect some sort of "nonlocal" statement similar to Python,  
> e.g.
> 
> def foo  
> &nbsp;&nbsp;nonlocal x  
> &nbsp;&nbsp;# I can access x in enclosing scope now  
> end

I thought you said you wanted elegance 🙂

> And no, I don't want to have to use global variables - that would just  
> be pollution and would be incredibly unwieldy in large projects.  
> Frankly, if there was a way to access local variables in enclosing  
> scopes, there wouldn't even need to be a special global variable  
> concept.

Have you looked at class\_eval and define\_method?

&nbsp;&nbsp;&nbsp;class MyClass; end  
&nbsp;&nbsp;&nbsp;m = "my\_method"  
&nbsp;&nbsp;&nbsp;MyClass.class\_eval do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;define\_method(m) { puts "Hi from #{m}!" }  
&nbsp;&nbsp;&nbsp;end

and similar.

David

> **···**
>
> On Sat, 1 Nov 2008, Yuh-Ruey Chen wrote:
> 
> --  
> Rails training from David A. Black and Ruby Power and Light:  
> &nbsp;&nbsp;&nbsp;Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL  
> &nbsp;&nbsp;&nbsp;Advancing with Rails January 19-22 Fort Lauderdale, FL \*  
> &nbsp;&nbsp;&nbsp;\* Co-taught with Patrick Ewing!  
> See [http://www.rubypal.com](http://www.rubypal.com) for details and updates!

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [31 October 2008 17:59 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/3 "2008-10-31T17:59:43Z")

</div>

Ruby, in it's infinite wisdom; gives you a cake that you can have and eat.

x = 42  
def a; x end # does not work!!  
Why?  
Because it is efficient, there is no closure and that means one  
context less to look up at runtime.

If however you want the closure (as I often do) you can still do it

x = 42

class \<\< self; self end.module\_eval do  
&nbsp;&nbsp;define\_method :a do x end  
&nbsp;&nbsp;define\_method :a= do |new\_x| x = new\_x end  
end

puts a  
a = 43  
puts a  
#! The next one is important !  
puts x

Note the class \<\< self; self end.module\_eval  
but I guess you know why I am doing this...

... class \<\< self  
end

does not create a closure.

HTH  
Robert

> **···**
>
> --  
> C'est véritablement utile puisque c'est joli.
> 
> Antoine de Saint Exupéry

---

<div class="post-metadata">

**Author:** ![Pit\_Capitain](https://avatars.discourse-cdn.com/v4/letter/p/d78d45/32.png) [@Pit\_Capitain](https://rubytalk.org/u/Pit_Capitain)\
**Post date:** [31 October 2008 18:31 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/4 "2008-10-31T18:31:30Z")

</div>

What is the difference between your "local" variable x, which should  
be accessible from everywhere, and a global variable?

Regards,  
Pit

> **···**
>
> 2008/10/31 Yuh-Ruey Chen \<maian330@gmail.com\>:
> 
> > x = 10
> > 
> > def foo  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# how to access x from here?  
> > end
> > 
> > class Klass  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# how to access x from here?  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def bar  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# how to access x from here?  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > end
> > 
> > And no, I don't want to have to use global variables - that would just  
> > be pollution and would be incredibly unwieldy in large projects.

---

<div class="post-metadata">

**Author:** ![Yuh-Ruey\_Chen](https://avatars.discourse-cdn.com/v4/letter/y/57b2e6/32.png) [@Yuh-Ruey\_Chen](https://rubytalk.org/u/Yuh-Ruey_Chen)\
**Post date:** [31 October 2008 18:34 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/5 "2008-10-31T18:34:00Z")

</div>

Thanks for the reply.

> \> My questions are within the following example:
> 
> \> x = 10
> 
> \> def foo  
> \> # how to access x from here?
> 
> \> end
> 
> \> class Klass  
> \> # how to access x from here?  
> \> def bar  
> \> # how to access x from here?  
> \> end  
> \> end
> 
> \> lambda { x } # I can access x here but why not in foo or Klass or bar?
> 
> I'm not sure what you mean by "why". Every language has scoping rules.  
> Ruby's rules include provision for closures, in that code blocks do  
> not start a new local scope and can be used as the bodies of anonymous  
> function objects.

I understand that they create new scopes, but what I don't get is why  
you can't access enclosing scopes! In most other languages, scopes are  
hierarchical, in that nested scopes will include parent scopes.

JS:

var x = 10  
function foo() {  
&nbsp;&nbsp;x // I can still access x!  
}

Python:

x = 10  
def foo():  
&nbsp;&nbsp;x # I can still access x!

Scheme:

(let ((x 10))  
&nbsp;&nbsp;&nbsp;&nbsp;((lambda ()  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x) ; I can still access x!  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;))

> There's no moral imperative, one way or the other. You're just  
> encountering and learning how Ruby handles these things. Relax 🙂
> 
> \> I sincerely hope I'm missing something here. To me, the inability to  
> \> access local variables in an enclosing scope is very counter-  
> \> intuitive. I thought Ruby was supposed to be elegant? At the very  
> \> least, I expect some sort of "nonlocal" statement similar to Python,  
> \> e.g.
> 
> \> def foo  
> \> nonlocal x  
> \> # I can access x in enclosing scope now  
> \> end
> 
> I thought you said you wanted elegance 🙂

I did explicitly say "at the very least". I'd rather not have to  
specify that "nonlocal x", but if it were necessary for the sake of  
compatibility, then so be it. And that's another issue: if Ruby  
provides all these methods that allow me to break encapsulation, I  
don't see why there isn't a method that allows me to access local vars  
in enclosing scopes. That's just inflexible.

With that said, I kinda understand why x can't simply refer to  
enclosing scopes, because it would be fragile: a method x would be  
added which would make x refer to that method instead of the var in  
the enclosing scope. That's why I think there needs to be some  
equivalent of "nonlocal x". For a more slightly more elegant example:

def foo  
&nbsp;&nbsp;$nonlocal.x  
end

or

def foo  
&nbsp;&nbsp;::x # don't know if this would conflict with anything  
end

> \> And no, I don't want to have to use global variables - that would just  
> \> be pollution and would be incredibly unwieldy in large projects.  
> \> Frankly, if there was a way to access local variables in enclosing  
> \> scopes, there wouldn't even need to be a special global variable  
> \> concept.
> 
> Have you looked at class\_eval and define\_method?
> 
> class MyClass; end  
> m = "my\_method"  
> MyClass.class\_eval do  
> define\_method(m) { puts "Hi from #{m}!" }  
> end
> 
> and similar.

Yes I'm familiar with them, and I actually would like to use them, but  
blocks can't have default arguments. Ideally, I would like to write  
everything with blocks and avoid all this magical "new scope"  
nonsense. It makes metaprogramming tricky in my experience.

> **···**
>
> On Oct 31, 12:55 pm, "David A. Black" \<dbl...@rubypal.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Yuh-Ruey\_Chen](https://avatars.discourse-cdn.com/v4/letter/y/57b2e6/32.png) [@Yuh-Ruey\_Chen](https://rubytalk.org/u/Yuh-Ruey_Chen)\
**Post date:** [31 October 2008 18:49 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/6 "2008-10-31T18:49:01Z")

</div>

> Ruby, in it's infinite wisdom; gives you a cake that you can have and eat.
> 
> x = 42  
> def a; x end # does not work!!  
> Why?  
> Because it is efficient, there is no closure and that means one  
> context less to look up at runtime.

Not particularly convinced with that. If Python handles it with ease  
and apparently no runtime performance penalty, I don't see why Ruby  
can't do the same.

I'm more convinced with the fragility argument I gave in my previous  
post, which is why I proposed the "nonlocal" thing.

> If however you want the closure (as I often do) you can still do it
> 
> x = 42
> 
> class \<\< self; self end.module\_eval do  
> define\_method :a do x end  
> define\_method :a= do |new\_x| x = new\_x end  
> end
> 
> puts a  
> a = 43  
> puts a  
> #! The next one is important !  
> puts x
> 
> Note the class \<\< self; self end.module\_eval  
> but I guess you know why I am doing this...
> 
> .. class \<\< self  
> end
> 
> does not create a closure.

That's pretty clever, albeit somewhat unreadable. I'd prefer to keep  
Ruby as readable as possible 🙂

> **···**
>
> On Oct 31, 12:59 pm, Robert Dober \<robert.do...@gmail.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Yuh-Ruey\_Chen](https://avatars.discourse-cdn.com/v4/letter/y/57b2e6/32.png) [@Yuh-Ruey\_Chen](https://rubytalk.org/u/Yuh-Ruey_Chen)\
**Post date:** [31 October 2008 18:49 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/7 "2008-10-31T18:49:16Z")

</div>

The difference that the local variable doesn't have to be defined in  
global scope. Only child scopes should have access to that local  
variable.

def foo  
&nbsp;&nbsp;a = 10  
&nbsp;&nbsp;def bar  
&nbsp;&nbsp;&nbsp;&nbsp;# should somehow be able to access a  
&nbsp;&nbsp;end  
&nbsp;&nbsp;bar  
end  
foo  
# here, we should not be able to access foo's a, but if there is  
another a in scope, we can access that

Or to put it in Python:

a = 20  
def foo():  
&nbsp;&nbsp;a = 10  
&nbsp;&nbsp;def bar():  
&nbsp;&nbsp;&nbsp;&nbsp;print a # prints 10  
&nbsp;&nbsp;bar()  
foo()  
print a # prints 20

> **···**
>
> On Oct 31, 1:31 pm, Pit Capitain \<pit.capit...@gmail.com\> wrote:
> 
> > 2008/10/31 Yuh-Ruey Chen \<maian...@gmail.com\>:
> > 
> > \> x = 10
> > 
> > \> def foo  
> > \> # how to access x from here?  
> > \> end
> > 
> > \> class Klass  
> > \> # how to access x from here?  
> > \> def bar  
> > \> # how to access x from here?  
> > \> end  
> > \> end
> > 
> > \> And no, I don't want to have to use global variables - that would just  
> > \> be pollution and would be incredibly unwieldy in large projects.
> > 
> > What is the difference between your "local" variable x, which should  
> > be accessible from everywhere, and a global variable?
> > 
> > Regards,  
> > Pit

---

<div class="post-metadata">

**Author:** ![Stefan\_Lang1](https://avatars.discourse-cdn.com/v4/letter/s/46a35a/32.png) [@Stefan\_Lang1](https://rubytalk.org/u/Stefan_Lang1)\
**Post date:** [31 October 2008 19:18 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/8 "2008-10-31T19:18:45Z")

</div>

The first assignment to a creates a \_module\_ scoped variable in Python.  
It is \_not\_ local, it can very well be accessed from anywhere via

&nbsp;&nbsp;&nbsp;&nbsp;import some\_module  
&nbsp;&nbsp;&nbsp;&nbsp;some\_module.a

Since it's a bad idea anyway to reassign such variables  
(metaprogramming might be an exception), you can use  
Ruby's constants for this purpose:

&nbsp;&nbsp;&nbsp;&nbsp;module MyModule

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A = 20

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# can access A from anywhere within MyModule,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# including method definitions, nested classes, etc.

&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;puts MyModule::A # access from outside of MyModule

At least anything that looks like local variable assignment  
in Ruby is actually local variable assignment. The thing to  
learn is that "module", "class" and "def" create new, empty  
local scopes, they have no enclosing scope with regards to  
local variables.

It is generally a better idea to genuinely try to understand  
a new language and its idioms instead of bending it to ones  
expectations from the beginning.

Stefan

> **···**
>
> 2008/10/31 Yuh-Ruey Chen \<maian330@gmail.com\>:
> 
> > The difference that the local variable doesn't have to be defined in  
> > global scope. Only child scopes should have access to that local  
> > variable.
> > 
> > def foo  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a = 10  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def bar  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# should somehow be able to access a  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar  
> > end  
> > foo  
> > # here, we should not be able to access foo's a, but if there is  
> > another a in scope, we can access that
> > 
> > Or to put it in Python:
> > 
> > a = 20  
> > def foo():  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a = 10  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def bar():  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print a # prints 10  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar()  
> > foo()  
> > print a # prints 20

---

<div class="post-metadata">

**Author:** ![Mike\_Gold](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@Mike\_Gold](https://rubytalk.org/u/Mike_Gold)\
**Post date:** [31 October 2008 19:20 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/9 "2008-10-31T19:20:12Z")

</div>

Yuh-Ruey Chen wrote:

> > � �MyClass.class\_eval do  
> > � � �define\_method(m) { puts "Hi from #{m}!" }  
> > � �end
> > 
> > and similar.
> 
> Yes I'm familiar with them, and I actually would like to use them, but  
> blocks can't have default arguments. Ideally, I would like to write  
> everything with blocks and avoid all this magical "new scope"  
> nonsense. It makes metaprogramming tricky in my experience.

I use often use Class.new and define\_method for just the reasons you  
describe: metaprogramming most naturally goes with locals bound to  
closures. This style also avoids a handful of potential problems with  
the "regular" way of using different scopes, in particular name  
conflicts and lack of true read-only protection for variables.

I was told that I wasn't doing things in a "rubyish" way. Disregard  
that BS. Use closures and define\_method for metaprogramming. Your code  
will be better.

Note 1.9 allows default arguments for lambdas as well as a &block  
parameter. 1.8.7 allows a &block parameter where 1.8.6 does not. For  
1.8.x you can get the same effect of default arguments like this

class \<\< self  
&nbsp;&nbsp;&nbsp;&nbsp;define\_method(:foo) { |\*args|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a, b =  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case args.size  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when 0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;["fred", "barney"]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[args.first, "barney"]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when 2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;args  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise ArgumentError,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"wrong number of arguments (#{args.size} for 2)"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "foo: #{a} #{b}"  
&nbsp;&nbsp;&nbsp;&nbsp;}  
end

foo #=\> foo: fred barney  
foo :a #=\> foo: a barney  
foo :a, :b #=\> foo: a b

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [1 November 2008 11:58 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/10 "2008-11-01T11:58:19Z")

</div>

> Not particularly convinced with that. If Python handles it with ease  
> and apparently no runtime performance penalty, I don't see why Ruby  
> can't do the same.

Of course Python pays a (small) penalty for the lookup.

Closures might be more expensive though because of the local copies. I  
however do not know  
how this is optimized in the different VM.  
Cheers  
Robert

---

<div class="post-metadata">

**Author:** ![Yuh-Ruey\_Chen](https://avatars.discourse-cdn.com/v4/letter/y/57b2e6/32.png) [@Yuh-Ruey\_Chen](https://rubytalk.org/u/Yuh-Ruey_Chen)\
**Post date:** [31 October 2008 19:34 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/11 "2008-10-31T19:34:00Z")

</div>

> \> The difference that the local variable doesn't have to be defined in  
> \> global scope. Only child scopes should have access to that local  
> \> variable.
> 
> \> def foo  
> \> a = 10  
> \> def bar  
> \> # should somehow be able to access a  
> \> end  
> \> bar  
> \> end  
> \> foo  
> \> # here, we should not be able to access foo's a, but if there is  
> \> another a in scope, we can access that
> 
> \> Or to put it in Python:
> 
> \> a = 20  
> \> def foo():  
> \> a = 10  
> \> def bar():  
> \> print a # prints 10  
> \> bar()  
> \> foo()  
> \> print a # prints 20
> 
> The first assignment to a creates a \_module\_ scoped variable in Python.  
> It is \_not\_ local, it can very well be accessed from anywhere via
> 
> ```
> import some\_module
> some\_module\.a
> 
> ```

Well then just wrap that example in another function:

def scope()  
&nbsp;&nbsp;a = 20  
&nbsp;&nbsp;def foo():  
&nbsp;&nbsp;&nbsp;&nbsp;a = 10  
&nbsp;&nbsp;&nbsp;&nbsp;def bar():  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print a # prints 10  
&nbsp;&nbsp;&nbsp;&nbsp;bar()  
&nbsp;&nbsp;foo()  
&nbsp;&nbsp;print a # prints 20  
scope()

My point was that scopes nest as expected.

> Since it's a bad idea anyway to reassign such variables  
> (metaprogramming might be an exception), you can use  
> Ruby's constants for this purpose:
> 
> ```
> module MyModule
> 
> A = 20
> 
> \# can access A from anywhere within MyModule,
> \# including method definitions, nested classes, etc\.
> 
> end
> 
> puts MyModule::A \# access from outside of MyModule
> 
> ```
> 
> At least anything that looks like local variable assignment  
> in Ruby is actually local variable assignment. The thing to  
> learn is that "module", "class" and "def" create new, empty  
> local scopes, they have no enclosing scope with regards to  
> local variables.
> 
> It is generally a better idea to genuinely try to understand  
> a new language and its idioms instead of bending it to ones  
> expectations from the beginning.
> 
> Stefan

I am trying to understand Ruby with some metaprogramming practice. But  
I still feel that this is a really backwards step in language design.

It's like telling me I should use GOTO in original BASIC instead of  
trying to bend the language to simulate while loops. Would any sane  
modern programmer do that?

> **···**
>
> On Oct 31, 2:18 pm, Stefan Lang \<perfectly.normal.hac...@gmail.com\> wrote:
> 
> > 2008/10/31 Yuh-Ruey Chen \<maian...@gmail.com\>:

---

<div class="post-metadata">

**Author:** ![Yuh-Ruey\_Chen](https://avatars.discourse-cdn.com/v4/letter/y/57b2e6/32.png) [@Yuh-Ruey\_Chen](https://rubytalk.org/u/Yuh-Ruey_Chen)\
**Post date:** [31 October 2008 19:38 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/12 "2008-10-31T19:38:58Z")

</div>

Oops, forgot to reply to this bit.

This is not what I'm really looking for. I don't care about accessing  
variables within another unrelated scope - in fact, unless explicitly  
allowed, it should not be allowed. I only care about accessing  
variables in enclosing scopes.

> **···**
>
> On Oct 31, 2:18 pm, Stefan Lang \<perfectly.normal.hac...@gmail.com\> wrote:
> 
> > Since it's a bad idea anyway to reassign such variables  
> > (metaprogramming might be an exception), you can use  
> > Ruby's constants for this purpose:
> > 
> > ```
> > module MyModule
> > 
> > A = 20
> > 
> > \# can access A from anywhere within MyModule,
> > \# including method definitions, nested classes, etc\.
> > 
> > end
> > 
> > puts MyModule::A \# access from outside of MyModule
> > 
> > ```

---

<div class="post-metadata">

**Author:** ![Stefan\_Lang1](https://avatars.discourse-cdn.com/v4/letter/s/46a35a/32.png) [@Stefan\_Lang1](https://rubytalk.org/u/Stefan_Lang1)\
**Post date:** [31 October 2008 20:09 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/13 "2008-10-31T20:09:13Z")

</div>

> Well then just wrap that example in another function:
> 
> def scope()  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a = 20  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def foo():  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a = 10  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def bar():  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print a # prints 10  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar()  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo()  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print a # prints 20  
> scope()

FWIW, Ruby doesn't have nested procedures like that.

> I am trying to understand Ruby with some metaprogramming practice. But  
> I still feel that this is a really backwards step in language design.
> 
> It's like telling me I should use GOTO in original BASIC instead of  
> trying to bend the language to simulate while loops. Would any sane  
> modern programmer do that?

I don't think it's a good analogy. Ruby is more oriented towards  
little objects and message passing than Pascal-like nested  
procedures.

I'm sure we could work out an elegant solution to some higher  
level goal than "accessing local variables", especially when it  
comes to metaprogramming.

Stefan

> **···**
>
> 2008/10/31 Yuh-Ruey Chen \<maian330@gmail.com\>:

---

<div class="post-metadata">

**Author:** ![Mike\_Gold](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@Mike\_Gold](https://rubytalk.org/u/Mike_Gold)\
**Post date:** [31 October 2008 20:19 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/14 "2008-10-31T20:19:31Z")

</div>

Yuh-Ruey Chen wrote:

> This is not what I'm really looking for. I don't care about accessing  
> variables within another unrelated scope - in fact, unless explicitly  
> allowed, it should not be allowed. I only care about accessing  
> variables in enclosing scopes.

Just to verify we are on the same page: define\_method solves all your  
problems, right? If you don't wish to use Ruby 1.9 (which will be  
officially released in two months) then the corner case is default  
arguments, which can be done via the example I gave.

Keep in mind that you are looking at just one side of the coin. There's  
a flip side to it. Preventing local variables from willy-nilly  
infecting your methods is a Good Thing, and is usually what you want.

> x = 10
> 
> def foo  
> &nbsp;&nbsp;# how to access x from here?  
> end
> 
> class Klass  
> &nbsp;&nbsp;# how to access x from here?  
> &nbsp;&nbsp;def bar  
> &nbsp;&nbsp;&nbsp;&nbsp;# how to access x from here?  
> &nbsp;&nbsp;end  
> end

If you really want x to be globally accessible then you should do

require 'ostruct'  
GLOBALS = OpenStruct.new  
GLOBALS.x = 10

def foo  
&nbsp;&nbsp;GLOBALS.x  
end

class Klass  
&nbsp;&nbsp;GLOBALS.x  
&nbsp;&nbsp;def bar  
&nbsp;&nbsp;&nbsp;&nbsp;GLOBALS.x  
&nbsp;&nbsp;end  
end

This makes your intention explicit. If you know python, you've probably  
heard the phrase, "Explicit is better than implicit." 🙂

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Yuh-Ruey\_Chen](https://avatars.discourse-cdn.com/v4/letter/y/57b2e6/32.png) [@Yuh-Ruey\_Chen](https://rubytalk.org/u/Yuh-Ruey_Chen)\
**Post date:** [31 October 2008 21:08 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/15 "2008-10-31T21:08:59Z")

</div>

> Yuh-Ruey Chen wrote:  
> \> This is not what I'm really looking for. I don't care about accessing  
> \> variables within another unrelated scope - in fact, unless explicitly  
> \> allowed, it should not be allowed. I only care about accessing  
> \> variables in enclosing scopes.
> 
> Just to verify we are on the same page: define\_method solves all your  
> problems, right? If you don't wish to use Ruby 1.9 (which will be  
> officially released in two months) then the corner case is default  
> arguments, which can be done via the example I gave.

I was not aware that this was being fixed. Thanks for the tip.

I've also noticed that there is a break in symmetry between |def| and |  
define\_method| besides this block issue. Compare:

x = 0  
C.define\_method(:foo) do  
&nbsp;&nbsp;puts x # refers to outside x  
&nbsp;&nbsp;puts self.x # refers and calls this object's method x  
end

with:

x = 0  
C.module\_eval do  
&nbsp;&nbsp;def foo  
&nbsp;&nbsp;&nbsp;&nbsp;# no way to refer to outside x, but something like |scope.x| would  
be nice for symmetry  
&nbsp;&nbsp;&nbsp;&nbsp;puts x # refers and calls this object's method x  
&nbsp;&nbsp;end  
end

These would be functionally equivalent if there were some way,  
analagous to the former's |self.x|, to access vars in enclosing  
scopes. I'd argue that such a symmetry would be elegant.

> Keep in mind that you are looking at just one side of the coin. There's  
> a flip side to it. Preventing local variables from willy-nilly  
> infecting your methods is a Good Thing, and is usually what you want.

I agree, it's a good thing.

x = 10  
def foo  
&nbsp;&nbsp;x # accessed outside x  
end

wouldn't be a good thing, because adding a new method called "x" would  
ruin it.

But something like:

x = 10  
def foo  
&nbsp;&nbsp;scope.x  
end

would not be as fragile, assuming |scope| is a new builtin method that  
does what you'd expect it do.

> If you really want x to be globally accessible then you should do
> 
> require 'ostruct'  
> GLOBALS = OpenStruct.new  
> GLOBALS.x = 10
> 
> def foo  
> GLOBALS.x  
> end
> 
> class Klass  
> GLOBALS.x  
> def bar  
> GLOBALS.x  
> end  
> end
> 
> This makes your intention explicit. If you know python, you've probably  
> heard the phrase, "Explicit is better than implicit." 🙂

Except I do NOT want x to be globally accessible. I just want to to be  
accessible be child scopes. If I wanted it to be globally accessible,  
then I would just use global variables.

> **···**
>
> On Oct 31, 3:19 pm, Mike Gold \<mike.gold.4...@gmail.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Yuh-Ruey\_Chen](https://avatars.discourse-cdn.com/v4/letter/y/57b2e6/32.png) [@Yuh-Ruey\_Chen](https://rubytalk.org/u/Yuh-Ruey_Chen)\
**Post date:** [31 October 2008 21:18 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/16 "2008-10-31T21:18:57Z")

</div>

> \> Well then just wrap that example in another function:
> 
> \> def scope()  
> \> a = 20  
> \> def foo():  
> \> a = 10  
> \> def bar():  
> \> print a # prints 10  
> \> bar()  
> \> foo()  
> \> print a # prints 20  
> \> scope()
> 
> FWIW, Ruby doesn't have nested procedures like that.

According to my copy of Ruby, it does.

> \> I am trying to understand Ruby with some metaprogramming practice. But  
> \> I still feel that this is a really backwards step in language design.
> 
> \> It's like telling me I should use GOTO in original BASIC instead of  
> \> trying to bend the language to simulate while loops. Would any sane  
> \> modern programmer do that?
> 
> I don't think it's a good analogy. Ruby is more oriented towards  
> little objects and message passing than Pascal-like nested  
> procedures.

Then why the first-class code blocks? Certainly makes Ruby a  
functional language, if only for blocks.

> I'm sure we could work out an elegant solution to some higher  
> level goal than "accessing local variables", especially when it  
> comes to metaprogramming.

The ability to access local vars in enclosing scopes is strictly  
unnecessary. But the same could also be said for instance\_variable\_get/  
defined?/set.

> **···**
>
> On Oct 31, 3:09 pm, Stefan Lang \<perfectly.normal.hac...@gmail.com\> wrote:
> 
> > 2008/10/31 Yuh-Ruey Chen \<maian...@gmail.com\>:

---

<div class="post-metadata">

**Author:** ![Stefan\_Lang1](https://avatars.discourse-cdn.com/v4/letter/s/46a35a/32.png) [@Stefan\_Lang1](https://rubytalk.org/u/Stefan_Lang1)\
**Post date:** [31 October 2008 22:19 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/17 "2008-10-31T22:19:33Z")

</div>

> > \> Well then just wrap that example in another function:
> > 
> > \> def scope()  
> > \> a = 20  
> > \> def foo():  
> > \> a = 10  
> > \> def bar():  
> > \> print a # prints 10  
> > \> bar()  
> > \> foo()  
> > \> print a # prints 20  
> > \> scope()
> > 
> > FWIW, Ruby doesn't have nested procedures like that.
> 
> According to my copy of Ruby, it does.

Looks can be deceiving:

&nbsp;&nbsp;&nbsp;&nbsp;$ cat nest\_def.rb  
&nbsp;&nbsp;&nbsp;&nbsp;class Foo  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def a  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "in a"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def b  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "in b"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;f = Foo.new  
&nbsp;&nbsp;&nbsp;&nbsp;p Foo.instance\_methods(false)  
&nbsp;&nbsp;&nbsp;&nbsp;f.a  
&nbsp;&nbsp;&nbsp;&nbsp;p Foo.instance\_methods(false)  
&nbsp;&nbsp;&nbsp;&nbsp;f.b  
&nbsp;&nbsp;&nbsp;&nbsp;$ ruby nest\_def.rb  
&nbsp;&nbsp;&nbsp;&nbsp;["a"]  
&nbsp;&nbsp;&nbsp;&nbsp;in a  
&nbsp;&nbsp;&nbsp;&nbsp;in b  
&nbsp;&nbsp;&nbsp;&nbsp;["b", "a"]  
&nbsp;&nbsp;&nbsp;&nbsp;in b

A def inside a method definition defines a method in  
self's class. It is not local to the enclosing method definition.

> > \> I am trying to understand Ruby with some metaprogramming practice. But  
> > \> I still feel that this is a really backwards step in language design.
> > 
> > \> It's like telling me I should use GOTO in original BASIC instead of  
> > \> trying to bend the language to simulate while loops. Would any sane  
> > \> modern programmer do that?
> > 
> > I don't think it's a good analogy. Ruby is more oriented towards  
> > little objects and message passing than Pascal-like nested  
> > procedures.
> 
> Then why the first-class code blocks? Certainly makes Ruby a  
> functional language, if only for blocks.

Yes, Ruby has a good deal of functional features and they  
fit in very nicely with the current scoping rules.

Although I'm not sure what you mean with "first class" code  
blocks. The block syntax is actually tied to message passing.

> > I'm sure we could work out an elegant solution to some higher  
> > level goal than "accessing local variables", especially when it  
> > comes to metaprogramming.
> 
> The ability to access local vars in enclosing scopes is strictly  
> unnecessary. But the same could also be said for instance\_variable\_get/  
> defined?/set.

Ruby does let you access local vars in enclosing scopes. It's  
only that your definition of enclosing scope differs from Ruby's.

Try to write some programs and you'll see it all fits together nicely.

Many design decisions may seem arbitrary. We could also debate  
the whole day about explicit self, assigning to local variables in  
outer scopes, etc. in Python. It's useless.

In the end, you'll find out what looks like a big problem now  
actually isn't. The most important usecase for your desired  
scoping rules would be nested functions, and Ruby doesn't  
have them. And for the other use cases, constants, class-  
and module instance variables suffice. OTOH, you can nest  
blocks as much as you like and scoping is what you expect.

Stefan

> **···**
>
> 2008/10/31 Yuh-Ruey Chen \<maian330@gmail.com\>:
> 
> > On Oct 31, 3:09 pm, Stefan Lang \<perfectly.normal.hac...@gmail.com\> \> wrote:
> > 
> > > 2008/10/31 Yuh-Ruey Chen \<maian...@gmail.com\>:

---

<div class="post-metadata">

**Author:** ![Mike\_Gold](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@Mike\_Gold](https://rubytalk.org/u/Mike_Gold)\
**Post date:** [31 October 2008 22:43 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/18 "2008-10-31T22:43:39Z")

</div>

> > Keep in mind that you are looking at just one side of the coin. �There's  
> > a flip side to it. �Preventing local variables from willy-nilly  
> > infecting your methods is a Good Thing, and is usually what you want.
> 
> I agree, it's a good thing.

Here you agree, but earlier in the same post you disagree:

Yuh-Ruey Chen wrote:

> I've also noticed that there is a break in symmetry between |def| and |  
> define\_method| besides this block issue. Compare:

The break in symmetry is intentional because it prevents local variables  
from willy-nilly infecting your methods, which you agreed is a good  
thing.

> These would be functionally equivalent if there were some way,  
> analagous to the former's |self.x|, to access vars in enclosing  
> scopes. I'd argue that such a symmetry would be elegant.
> 
> x = 10  
> def foo  
> &nbsp;&nbsp;x # accessed outside x  
> end
> 
> wouldn't be a good thing, because adding a new method called "x" would  
> ruin it.
> 
> But something like:
> 
> x = 10  
> def foo  
> &nbsp;&nbsp;scope.x  
> end
> 
> would not be as fragile, assuming |scope| is a new builtin method that  
> does what you'd expect it do.

But then you've missed out on the advantage of lexical local variables.  
What you propose takes the "lexical" out of "lexical scope". It is just  
nested variables which are visible from other scopes.

If that is what you wish, then you do not mean local (lexical)  
variables. You mean shared data, and Ruby wants you to be explicit  
about when you want shared data that will "infect" your method and class  
definitions. This is a good thing.

require 'ostruct'

module Top  
&nbsp;&nbsp;SHARED = OpenStruct.new  
&nbsp;&nbsp;SHARED.x = 10

&nbsp;&nbsp;class Foo  
&nbsp;&nbsp;&nbsp;&nbsp;def bar  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p SHARED.x  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

Top::Foo.new.bar #=\> 10

Lexical variables are used when you most definitely DO NOT want that.  
It is useful to have this distinction, because with lexicals you are  
guaranteed that no such infection can occur. (Unless you explicitly  
want it via define\_method.)

> > class Klass  
> > � GLOBALS.x  
> > � def bar  
> > � � GLOBALS.x  
> > � end  
> > end
> > 
> > This makes your intention explicit. �If you know python, you've probably  
> > heard the phrase, "Explicit is better than implicit." �:)
> 
> Except I do NOT want x to be globally accessible. I just want to to be  
> accessible be child scopes. If I wanted it to be globally accessible,  
> then I would just use global variables.

So don't make it global, as in the Top example above.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![a11](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/a11/32/8169_2.png) [@a11](https://rubytalk.org/u/a11)\
**Post date:** [1 November 2008 05:40 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/19 "2008-11-01T05:40:56Z")

</div>

you can write it yourself now

cfp:~ \> cat a.rb  
class C  
&nbsp;&nbsp;&nbsp;include(  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Module.new do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = 42  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def x() y end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;define\_method :method\_missing do |\_|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((\_ = local\_variables.index(\_.to\_s)))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eval local\_variables[\_]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;)  
end

p C.new.x

cfp:~ \> ruby a.rb  
42

i might add, however, that a function that has access to non-local state it generally called 'a method on an object with instance variables' and ruby has several methods to accomplish this . one very simple method is this

cfp:~ \> cat a.rb  
object = Module.new do  
&nbsp;&nbsp;&nbsp;@x = 42

&nbsp;&nbsp;&nbsp;def y() @x end

&nbsp;&nbsp;&nbsp;extend self  
end

p object.y

cfp:~ \> ruby a.rb  
42

and of course there are many more.

regards.

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

> **···**
>
> On Oct 31, 2008, at 3:08 PM, Yuh-Ruey Chen wrote:
> 
> > But something like:
> > 
> > x = 10  
> > def foo  
> > &nbsp;&nbsp;scope.x  
> > end
> > 
> > would not be as fragile, assuming |scope| is a new builtin method that  
> > does what you'd expect it do.
> 
> --  
> we can deny everything, except that we have the possibility of being better. simply reflect on that.  
> h.h. the 14th dalai lama

---

<div class="post-metadata">

**Author:** ![Yuh-Ruey\_Chen](https://avatars.discourse-cdn.com/v4/letter/y/57b2e6/32.png) [@Yuh-Ruey\_Chen](https://rubytalk.org/u/Yuh-Ruey_Chen)\
**Post date:** [1 November 2008 07:59 UTC](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930/20 "2008-11-01T07:59:11Z")

</div>

Replying to multiple posts:

> \>\> FWIW, Ruby doesn't have nested procedures like that.
> 
> \> According to my copy of Ruby, it does.
> 
> Looks can be deceiving:
> 
> &nbsp;&nbsp;&nbsp;&nbsp;$ cat nest\_def.rb  
> &nbsp;&nbsp;&nbsp;&nbsp;class Foo  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def a  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "in a"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def b  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "in b"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;f = Foo.new  
> &nbsp;&nbsp;&nbsp;&nbsp;p Foo.instance\_methods(false)  
> &nbsp;&nbsp;&nbsp;&nbsp;f.a  
> &nbsp;&nbsp;&nbsp;&nbsp;p Foo.instance\_methods(false)  
> &nbsp;&nbsp;&nbsp;&nbsp;f.b  
> &nbsp;&nbsp;&nbsp;&nbsp;$ ruby nest\_def.rb  
> &nbsp;&nbsp;&nbsp;&nbsp;["a"]  
> &nbsp;&nbsp;&nbsp;&nbsp;in a  
> &nbsp;&nbsp;&nbsp;&nbsp;in b  
> &nbsp;&nbsp;&nbsp;&nbsp;["b", "a"]  
> &nbsp;&nbsp;&nbsp;&nbsp;in b
> 
> A def inside a method definition defines a method in  
> self's class. It is not local to the enclosing method definition.

Wow, I did not realize that. That changes my thinking a lot.

> \>\> \> I am trying to understand Ruby with some metaprogramming practice. But  
> \>\> \> I still feel that this is a really backwards step in language design.
> 
> \>\> \> It's like telling me I should use GOTO in original BASIC instead of  
> \>\> \> trying to bend the language to simulate while loops. Would any sane  
> \>\> \> modern programmer do that?
> 
> \>\> I don't think it's a good analogy. Ruby is more oriented towards  
> \>\> little objects and message passing than Pascal-like nested  
> \>\> procedures.
> 
> \> Then why the first-class code blocks? Certainly makes Ruby a  
> \> functional language, if only for blocks.
> 
> Yes, Ruby has a good deal of functional features and they  
> fit in very nicely with the current scoping rules.
> 
> Although I'm not sure what you mean with "first class" code  
> blocks. The block syntax is actually tied to message passing.

Well, blocks aren't first class per-se, but they can easily be turned  
into first-class procs.

> \>\> I'm sure we could work out an elegant solution to some higher  
> \>\> level goal than "accessing local variables", especially when it  
> \>\> comes to metaprogramming.
> 
> \> The ability to access local vars in enclosing scopes is strictly  
> \> unnecessary. But the same could also be said for instance\_variable\_get/  
> \> defined?/set.
> 
> Ruby does let you access local vars in enclosing scopes. It's  
> only that your definition of enclosing scope differs from Ruby's.
> 
> Try to write some programs and you'll see it all fits together nicely.
> 
> Many design decisions may seem arbitrary. We could also debate  
> the whole day about explicit self, assigning to local variables in  
> outer scopes, etc. in Python. It's useless.
> 
> In the end, you'll find out what looks like a big problem now  
> actually isn't. The most important usecase for your desired  
> scoping rules would be nested functions, and Ruby doesn't  
> have them. And for the other use cases, constants, class-  
> and module instance variables suffice. OTOH, you can nest  
> blocks as much as you like and scoping is what you expect.

I recognize that access to nonlocal vars can be simulated with  
instance variables. It does seem weird to allow two different  
paradigms that interact with each other in a confusing - or at the  
least non-trivial - matter (just look at my confusion).

I guess my big beef with Ruby is that it is too complex and bloated  
with features that often are inconsistent or lack symmetry with each  
other. It's too "magical", making it hard to learn exactly how the  
language works. From a language design perspective, Ruby really seems  
like a mess to me, although with moments of brilliance. Most of the  
time, when I'm metaprogramming, I'm guessing and looking at the  
output, hoping I got so-and-so quirk correct.

Actually, I think this all could be mitigated to a certain extent if  
the documentation for Ruby were improved. I could not find an official  
language reference besides the API documentation, which is not  
sufficient by itself. Obviously it did not contain much information on  
scoping or non-API language features.

> \>\> Keep in mind that you are looking at just one side of the coin. There's  
> \>\> a flip side to it. Preventing local variables from willy-nilly  
> \>\> infecting your methods is a Good Thing, and is usually what you want.
> 
> \> I agree, it's a good thing.
> 
> Here you agree, but earlier in the same post you disagree:
> 
> Yuh-Ruey Chen wrote:  
> \> I've also noticed that there is a break in symmetry between |def| and |  
> \> define\_method| besides this block issue. Compare:
> 
> The break in symmetry is intentional because it prevents local variables  
> from willy-nilly infecting your methods, which you agreed is a good  
> thing.

I agreed in the sense that without extra syntax, it would be fragile,  
but as my example pointed out, it doesn't necessarily have to be  
fragile.

> \> These would be functionally equivalent if there were some way,  
> \> analagous to the former's |self.x|, to access vars in enclosing  
> \> scopes. I'd argue that such a symmetry would be elegant.
> 
> \> x = 10  
> \> def foo  
> \> x # accessed outside x  
> \> end
> 
> \> wouldn't be a good thing, because adding a new method called "x" would  
> \> ruin it.
> 
> \> But something like:
> 
> \> x = 10  
> \> def foo  
> \> scope.x  
> \> end
> 
> \> would not be as fragile, assuming |scope| is a new builtin method that  
> \> does what you'd expect it do.
> 
> But then you've missed out on the advantage of lexical local variables.  
> What you propose takes the "lexical" out of "lexical scope". It is just  
> nested variables which are visible from other scopes.

No, what I am proposing is a mechanism for lexical scope. This is what  
I mean with that |scope.x| - treat x as if it were from an enclosing  
scope.

> \>\> class Klass  
> \>\> GLOBALS.x  
> \>\> def bar  
> \>\> GLOBALS.x  
> \>\> end  
> \>\> end
> 
> \>\> This makes your intention explicit. If you know python, you've probably  
> \>\> heard the phrase, "Explicit is better than implicit." 🙂
> 
> \> Except I do NOT want x to be globally accessible. I just want to to be  
> \> accessible be child scopes. If I wanted it to be globally accessible,  
> \> then I would just use global variables.
> 
> So don't make it global, as in the Top example above.

But they are not local variables. Local vars for a function are  
created each time the function is called. Having access to those local  
vars outside of the function makes no sense at all.

> **···**
>
> On Oct 31, 5:19 pm, Stefan Lang \<perfectly.normal.hac...@gmail.com\> wrote:
> 
> > 2008/10/31 Yuh-Ruey Chen \<maian...@gmail.com\>:  
> > \> On Oct 31, 3:09 pm, Stefan Lang \<perfectly.normal.hac...@gmail.com\> \> \> wrote:
> 
> On Oct 31, 5:43 pm, Mike Gold \<mike.gold.4...@gmail.com\> wrote:
> 
> On Nov 1, 12:40 am, "ara.t.howard" \<ara.t.how...@gmail.com\> wrote:
> 
> > On Oct 31, 2008, at 3:08 PM, Yuh-Ruey Chen wrote:
> > 
> > \> But something like:
> > 
> > \> x = 10  
> > \> def foo  
> > \> scope.x  
> > \> end
> > 
> > \> would not be as fragile, assuming |scope| is a new builtin method that  
> > \> does what you'd expect it do.
> > 
> > you can write it yourself now
> > 
> > cfp:~ \> cat a.rb  
> > class C  
> > &nbsp;&nbsp;&nbsp;include(  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Module.new do  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y = 42  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def x() y end
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;define\_method :method\_missing do |\_|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((\_ = local\_variables.index(\_.to\_s)))  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eval local\_variables[\_]  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;)  
> > end
> > 
> > p C.new.x
> > 
> > cfp:~ \> ruby a.rb  
> > 42
> 
> That's, um, interesting. Less efficient than I hoped, but then again  
> Ruby is not known for its efficiency. Though that method\_missing does  
> give me an idea...

[Next page](https://rubytalk.org/t/how-to-access-to-local-variables-in-enclosing-scopes/49930.md?page=2)
