user2399453
user2399453

Reputation: 3081

Ruby object references

I came across a snippet of code in Ruby that confused me. Boiling it down to a simple example below to illustrate. Why is it that sArr does not have its contents automatically updated in the first case but it happens in the second case? The snippets are short and self explanatory with three returns separating the two scenarios.

2.0.0-p598 :068 > str = "Hello"
=> "Hello" 
2.0.0-p598 :069 > sArr = [str]
=> ["Hello"] 
2.0.0-p598 :070 > str = str.upcase
=> "HELLO" 
2.0.0-p598 :071 > str
=> "HELLO" 
2.0.0-p598 :072 > sArr
=> ["Hello"]  # Why is this not ["HELLO"] like in the sequence below?
2.0.0-p598 :073 > 
2.0.0-p598 :074 >   
2.0.0-p598 :075 >   
2.0.0-p598 :076 >   str = "Hello"
=> "Hello" 
2.0.0-p598 :077 > sArr = [str]
=> ["Hello"] 
2.0.0-p598 :078 > str.upcase!
=> "HELLO" 
2.0.0-p598 :079 > sArr
=> ["HELLO"] 

Upvotes: 1

Views: 69

Answers (1)

Matt
Matt

Reputation: 20796

This is because a new String instance is created with str = str.upcase but not str.upcase!:

str = "Hello"
str.object_id
# => 70132476337960 
str = str.upcase
# => "HELLO" 
str.object_id
# => 70132476374360 (new instance)

str = "Hello"
str.object_id
# => 70132476415240 
str.upcase!
# => "HELLO" 
str.object_id
# => 70132476415240 (same instance)

sArr is unaffected by str = str.upcase since it is holding a reference to the initial "Hello". Assigning to str doesn't change the object in sArr any more than if you did str = 'World'. In contrast, str.upcase! modifies the instance held by sArr.

Upvotes: 5

Related Questions