An immutable style creates an updated value instead of changing the original value.

immutable update Ruby objects can be mutable, but methods like `merge` make it easy to create updated copies.

Immutable Style

bonus
immutable_style.rb
Replay: real traced execution (multi-file project)
bonus = 2
original = { name: "Ada", score: 8 }

new_score = original[:score] + bonus
updated = original.merge(score: new_score)

original_score = original[:score]
updated_score = updated[:score]

puts "bonus=#{bonus}"
puts "original_score=#{original_score}"
puts "updated_score=#{updated_score}"
puts "same_object=#{original.object_id == updated.object_id}"
bonus = 0
original = { name: "Ada", score: 8 }

new_score = original[:score] + bonus
updated = original.merge(score: new_score)

original_score = original[:score]
updated_score = updated[:score]

puts "bonus=#{bonus}"
puts "original_score=#{original_score}"
puts "updated_score=#{updated_score}"
puts "same_object=#{original.object_id == updated.object_id}"
bonus = 5
original = { name: "Ada", score: 8 }

new_score = original[:score] + bonus
updated = original.merge(score: new_score)

original_score = original[:score]
updated_score = updated[:score]

puts "bonus=#{bonus}"
puts "original_score=#{original_score}"
puts "updated_score=#{updated_score}"
puts "same_object=#{original.object_id == updated.object_id}"
  1. bonus ← 2, original ← {:name=>"Ada", :score=>8}, new_score ← 10

    1bonus→ 2 = 2  #@bonus=0, 52original→ {:name=>"Ada", :score=>8} = { name: "Ada", score: 8 }34new_score→ 10 = original[:score]8 + bonus25updated→ {:name=>"Ada", :score=>10} = original.merge(score: new_score){:name=>"Ada", :score=>10}67original_score→ 8 = original[:score]88updated_score→ 10 = updated[:score]10910puts "bonus=#{bonus2}"11puts "original_score=#{original_score8}"12puts "updated_score=#{updated_score10}"13puts "same_object=#{original.object_id80 == updated.object_id100}"
    outputbonus=2
    original_score=8
    updated_score=10
    same_object=false
  1. bonus ← 0, original ← {:name=>"Ada", :score=>8}, new_score ← 8

    1bonus→ 0 = 02original→ {:name=>"Ada", :score=>8} = { name: "Ada", score: 8 }34new_score→ 8 = original[:score]8 + bonus05updated→ {:name=>"Ada", :score=>8} = original.merge(score: new_score){:name=>"Ada", :score=>8}67original_score→ 8 = original[:score]88updated_score→ 8 = updated[:score]8910puts "bonus=#{bonus0}"11puts "original_score=#{original_score8}"12puts "updated_score=#{updated_score8}"13puts "same_object=#{original.object_id80 == updated.object_id100}"
    outputbonus=0
    original_score=8
    updated_score=8
    same_object=false
  1. bonus ← 5, original ← {:name=>"Ada", :score=>8}, new_score ← 13

    1bonus→ 5 = 52original→ {:name=>"Ada", :score=>8} = { name: "Ada", score: 8 }34new_score→ 13 = original[:score]8 + bonus55updated→ {:name=>"Ada", :score=>13} = original.merge(score: new_score){:name=>"Ada", :score=>13}67original_score→ 8 = original[:score]88updated_score→ 13 = updated[:score]13910puts "bonus=#{bonus5}"11puts "original_score=#{original_score8}"12puts "updated_score=#{updated_score13}"13puts "same_object=#{original.object_id80 == updated.object_id100}"
    outputbonus=5
    original_score=8
    updated_score=13
    same_object=false