Home > Software engineering >  RUBY: Using An Array of Structs
RUBY: Using An Array of Structs

Time:11-25

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.

  • Related