# Scope questions

**URL:** <https://www.ruby-forum.com/t/scope-questions/114888>\
**Category:** Ruby\
**Created:** [September 18, 2007, 4:31pm UTC](https://www.ruby-forum.com/t/scope-questions/114888 "2007-09-18T16:31:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mister\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/dec6dc/32.png) [@Mister\_R](https://www.ruby-forum.com/u/Mister_R)\
**Post date:** [September 18, 2007, 4:31pm UTC](https://www.ruby-forum.com/t/scope-questions/114888/1 "2007-09-18T16:31:28Z")

</div>

Hi guys, I am a recent Ruby convert (from PERL), and I am wondering if  
there  
is a way to get some of the behavior that I am  
comfortable with with regards to scope.

In PERL the following code:

my $var=1;  
{  
my $var=2;  
print “inner=$var\n”  
}  
print “outer=$var\n”

yields:

inner=2  
outer=1

However in Ruby, I’m not sure how to get the same behavior. I tried:

var=1  
begin  
var=2  
print “inner=#{var}\n”  
end  
print “outer=#{var}\n”

which yields a different output than the PERL code. Is this type of  
thing  
possible in Ruby without creating a class?

Thanks!

---

<div class="post-metadata">

**Author:** ![Mister\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/dec6dc/32.png) [@Mister\_R](https://www.ruby-forum.com/u/Mister_R)\
**Post date:** [September 18, 2007, 4:51pm UTC](https://www.ruby-forum.com/t/scope-questions/114888/2 "2007-09-18T16:51:31Z")

</div>

On Tue, Sep 18, 2007 at 11:29:25PM +0900, Mister R. wrote:

> my $var=1;  
> {  
> my $var=2;  
> print “inner=$var\n”  
> }  
> print “outer=$var\n”

If the variables really are different, then use a different variable  
name. Even though you can do this in perl, that does not make it a good  
idea.

Methods should, in general, be short enough that you do not have naming  
conflicts between local variables. If you find yourself running into  
this a lot, you are probably doing too much in one method, which can  
make code harder to read and to refactor later on.

Matz has discussed some syntaxes for what you want for Ruby 2.0, such  
as:

var = 1  
local { |var|  
var = 2  
}  
puts var #=\> 1

(so that block parameters are always local to the block) but I don’t  
know what the current status of this is.

Paul

---

<div class="post-metadata">

**Author:** ![Mister\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/dec6dc/32.png) [@Mister\_R](https://www.ruby-forum.com/u/Mister_R)\
**Post date:** [September 18, 2007, 6:00pm UTC](https://www.ruby-forum.com/t/scope-questions/114888/3 "2007-09-18T18:00:47Z")

</div>

On 9/18/07, Mister R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> which yields a different output than the PERL code. Is this type of thing  
> possible in Ruby without creating a class?

is def method good enough for you?

irb(main):001:0\> def m  
irb(main):002:1\> var = 2  
irb(main):003:1\> puts “inner var = #{var}”  
irb(main):004:1\> end  
=\> nil  
irb(main):005:0\> var = 1  
=\> 1  
irb(main):006:0\> m  
inner var = 2  
=\> nil  
irb(main):007:0\> puts “outer var = #{var}”  
outer var = 1  
=\> nil

you can nest methods too

irb(main):008:0\> def m2  
irb(main):009:1\> var = 1  
irb(main):010:1\> def m3  
irb(main):011:2\> var = 2  
irb(main):012:2\> puts “inner var = #{var}”  
irb(main):013:2\> end  
irb(main):014:1\> puts “outer var = #{var}”  
irb(main):015:1\> end  
=\> nil  
irb(main):016:0\> m2  
outer var = 1  
=\> nil  
irb(main):017:0\> m2.m3  
outer var = 1  
inner var = 2  
=\> nil  
irb(main):018:0\> m3  
inner var = 2  
=\> nil

kind regards -botp

---

<div class="post-metadata">

**Author:** ![Mister\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/dec6dc/32.png) [@Mister\_R](https://www.ruby-forum.com/u/Mister_R)\
**Post date:** [September 20, 2007, 3:43pm UTC](https://www.ruby-forum.com/t/scope-questions/114888/4 "2007-09-20T15:43:26Z")

</div>

On Wed, Sep 19, 2007 at 12:59:58AM +0900, botp wrote:

> outer var = 1  
> =\> nil  
> irb(main):017:0\> m2.m3  
> outer var = 1  
> inner var = 2  
> =\> nil  
> irb(main):018:0\> m3  
> inner var = 2  
> =\> nil

This might not be doing what you think it is:

irb(main):020:0\> $VERBOSE = true  
=\> true  
irb(main):023:0\> m2.m3  
(irb):9: warning: method redefined; discarding old m3  
outer var = 1  
inner var = 2  
=\> nil  
irb(main):024:0\> m2  
(irb):9: warning: method redefined; discarding old m3  
outer var = 1  
=\> nil  
irb(main):025:0\> nil.m3  
inner var = 2  
=\> nil

(your example made it look like m3 is inside m2, which it isn’t. m2 is  
returning nil, and since you made m3 a public method, m2.m3 is the same  
as  
m2(); nil.m3())

Paul

---

<div class="post-metadata">

**Author:** ![Mister\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/dec6dc/32.png) [@Mister\_R](https://www.ruby-forum.com/u/Mister_R)\
**Post date:** [September 21, 2007, 6:19am UTC](https://www.ruby-forum.com/t/scope-questions/114888/5 "2007-09-21T06:19:38Z")

</div>

From: Paul B. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]

# On Wed, Sep 19, 2007 at 12:59:58AM +0900, botp wrote:

# \> irb(main):008:0\> def m2

# \> irb(main):009:1\> var = 1

# \> irb(main):010:1\> def m3

# \> irb(main):011:2\> var = 2

# \> irb(main):012:2\> puts “inner var = #{var}”

# \> irb(main):013:2\> end

# \> irb(main):014:1\> puts “outer var = #{var}”

# \> irb(main):015:1\> end

# \> =\> nil

# \> irb(main):016:0\> m2

# \> outer var = 1

# \> =\> nil

# \> irb(main):017:0\> m2.m3

# \> outer var = 1

# \> inner var = 2

# \> =\> nil

# \> irb(main):018:0\> m3

# \> inner var = 2

# \> =\> nil

# 

# This might not be doing what you think it is:

# 

# irb(main):020:0\> $VERBOSE = true

# =\> true

# irb(main):023:0\> m2.m3

# (irb):9: warning: method redefined; discarding old m3

# outer var = 1

# inner var = 2

# =\> nil

# irb(main):024:0\> m2

# (irb):9: warning: method redefined; discarding old m3

# outer var = 1

# =\> nil

# irb(main):025:0\> nil.m3

# inner var = 2

# =\> nil

my bad. sorry for the confusion.

i simply meant that you can define m3 inside m2, and that its var will  
not clash with that of m2, and that you can only invoke m3 if you’ve  
invoked m2 already.

in other words, you cannot do m3 right away. you’ll have to do m2 first,  
or if you wish to run m3 immediately, you may follow it thru after m2,  
or m2.m3. i guess it would be clearer if i nest it further like  
m1.m2.m3.m4. i could go that route to reach m4 immediately, or just wait  
and just do m1; then later, m2, then later m3… from then on m4 will  
be defined and i could then just invoke it plainly as m4. (of course by  
this behaviour, one can also redefine methods by inserting them within  
methods)

pls correct me if i’m wrong, i usually make stupid assumptions based on  
my limited experience. pardon a nuby pls ☹

kind regards -botp
