Here is my code. When I write to one variable all the elements change. (It is a bowling program)
Frame = Struct.new(:first, :second, :total)
frame = Frame.new(1,2,3)
frames = Array.new(11,frame)
print "frames[0].first: " frames[0].first.to_s newLine
print "frames[1].first: " frames[1].first.to_s newLine
game[0].first = 10
print "frames[0].first: " frames[0].first.to_s newLine
print "frames[1].first: " frames[1].first.to_s newLine
frames[1].first = 20
print "frames[0].first: " frames[0].first.to_s newLine
print "frames[1].first: " frames[1].first.to_s newLine
print out:
frames[0].first: 1
frames[1].first: 1
frames[0].first: 10
frames[1].first: 10
frames[0].first: 20
frames[1].first: 20
CodePudding user response:
As Sergio Tulentsev already wrote, the behavior you observe happens because you reference the exact same Frame
into all array slots.
Instead you can create new and different frames for each array slots by using Array.new
with a block:
Frame = Struct.new(:first, :second, :total)
frames = Array.new(11) { Frame.new(1, 2, 3) }
Btw when you change from print
to puts
then newlines will be added automatically to the end of the output. And when you use string interpolation instead of string concatenation then there is no need to call to_s
explicitly because string interpolation calls to_s
implicit.
puts "frames[0].first: #{frames[0].first}"
puts "frames[1].first: #{frames[1].first}"
game[0].first = 10
puts "frames[0].first: #{frames[0].first}"
puts "frames[1].first: #{frames[1].first}"
frames[1].first = 20
puts "frames[0].first: #{frames[0].first}"
puts "frames[1].first: #{frames[1].first}"
CodePudding user response:
all the elements change
array's elements are all references to the same underlying Frame object. When you use one of the references to mutate the object, the changes are observable through the other references.