# Confused by scope in ruby

**URL:** <https://www.ruby-forum.com/t/confused-by-scope-in-ruby/147089>\
**Category:** Ruby\
**Created:** [August 28, 2008, 11:59am UTC](https://www.ruby-forum.com/t/confused-by-scope-in-ruby/147089 "2008-08-28T11:59:01Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [August 28, 2008, 11:59am UTC](https://www.ruby-forum.com/t/confused-by-scope-in-ruby/147089/1 "2008-08-28T11:59:01Z")

</div>

Hello,

I’ve been writing in ruby for a bit, but ran into something while  
working on a project that struck me as weird, and could not find a ready  
explanation.

Sorry if this is something super basic…

Here is a simplified example.

My question is: Why is the hash not empty at the end?

class Hmmm  
def why\_not\_empty?  
hash = {}  
puts “Start: hash = #{hash.to\_s}”  
[1, 2, 3, 4, 5].each do |num|  
put\_in\_hash(num, hash)  
end  
puts “End hash:\n#{hash.to\_s}” # i would expect this to be {}  
end

def put\_in\_hash(num, hsh)  
hsh[num.to\_s] = “hello from hash index #{num}.\n”  
return nil  
end

def number  
num = 2  
puts “Start number: #{num}”  
change\_number?(num)  
puts “End number: #{num}”  
end

def change\_number?(num)  
num = 3  
end  
end

@a = Hmmm.new  
@a.why\_not\_empty?  
@a.number

Output:  
Start: hash =  
End hash:  
1hello from hash index 1.  
2hello from hash index 2.  
3hello from hash index 3.  
4hello from hash index 4.  
5hello from hash index 5.  
Start number: 2  
End number: 2

The number, as I would expect, stays at two, but the hash is actually  
changed by the method, as if I were passing it a pointer in C or  
something…

---

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [August 28, 2008, 12:11pm UTC](https://www.ruby-forum.com/t/confused-by-scope-in-ruby/147089/2 "2008-08-28T12:11:46Z")

</div>

Actually, it appears that I was googling wrong:

If anyone else is curious:

[http://www.ruby-forum.com/topic/163970](http://www.ruby-forum.com/topic/163970)  
[http://www.ruby-forum.com/topic/57549](http://www.ruby-forum.com/topic/57549)  
[http://www.ruby-forum.com/topic/119188](http://www.ruby-forum.com/topic/119188)  
[http://www.ruby-forum.com/topic/95594](http://www.ruby-forum.com/topic/95594)  
[http://www.ruby-forum.com/topic/139257](http://www.ruby-forum.com/topic/139257)

> **[Object \*\*arr;](http://al2o3-cr.blogspot.com/2008/08/object-arr.html)**
>
> What? What do these asterisks do? We're having Ruby here, and the whole old pointers things from C++ are gone, aren't they? Well, they are ...

---

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [August 28, 2008, 12:14pm UTC](https://www.ruby-forum.com/t/confused-by-scope-in-ruby/147089/3 "2008-08-28T12:14:33Z")

</div>

Mischa F. wrote:

> The number, as I would expect, stays at two, but the hash is actually  
> changed by the method, as if I were passing it a pointer in C or  
> something…

Well, that’s exactly what’s happening at C level - in both cases. The  
difference is that if you do foo[bar] = baz or  
foo.method\_that\_changes\_foo!  
then you change the object that foo points to (so all other variables  
that  
point to the same object will also reflect those changes), but if you do  
foo = bar, you’re just changing the pointer, i.e. foo now points to  
wherever  
bar points to and the object that it previously pointed to is unchanged.

HTH,  
Sebastian

---

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [August 28, 2008, 12:17pm UTC](https://www.ruby-forum.com/t/confused-by-scope-in-ruby/147089/4 "2008-08-28T12:17:55Z")

</div>

Mischa F. wrote:

> Hello,
> 
> I’ve been writing in ruby for a bit, but ran into something while  
> working on a project that struck me as weird, and could not find a ready  
> explanation.

Assigning a value to a parameter simply assigns a new variable to the  
letter, and adding something to a hash modifies the existing object,  
referenced by the variable. Similarily if you pass a string to a method  
def change(s) and inside the method do:  
s=“abc” # does not change the original object  
s+=“abc” # does not change the original object, because it is equivalent  
to s=s+“abc”  
s\<\<“abc” # does change the outside object because it is an in-place  
modification  
s.upcase! # does change  
s=s.upcase # does not

Have a look: [Ruby (Al2O3::Cr)](http://al2o3-cr.blogspot.com/2008/08/object-arr.html)

TPR.

---

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [August 28, 2008, 10:42pm UTC](https://www.ruby-forum.com/t/confused-by-scope-in-ruby/147089/5 "2008-08-28T22:42:43Z")

</div>

Yes, that is helpful. Thank you both.
