An empty array is defined outside a block and within the block, it is assigned to a new variable. If the new array changes, the empty array also modifies its values. Why?
# THIS CODE CHECK WHICH LETTERS IN klas APPEAR IN docs
klas = ["a", "b", "c"]
docs = [[1, "a"], [2, "a"], [3, "b"], [4, "b"], [5, "c"], [6, "c"]]
output = []
empty_array = Array.new(klas.size) { 0 } # EMPTY ARRAY DEFINED HERE
docs.each do |doc|
puts empty_array.inspect
puts (output_row = empty_array).inspect # EMPTY ARRAY ASSIGNED TO ANOTHER
# FIND INDEX OF THE LETTER IN klas FROM docs. ASSIGN 1.
output_row[klas.index(doc[1])] = 1 # PROBLEM! THIS ALSO CHANGES THE EMPTY ARRAY VALUES
output << output_row
end
CONSOLE OUTPUT to show empty array changing its value based on another array
###
empty_array is [0, 0, 0]
output_row is [0, 0, 0]
---
###
empty_array is [1, 0, 0]
output_row is [1, 0, 0]
---
###
empty_array is [1, 0, 0]
output_row is [1, 0, 0]
---
###
empty_array is [1, 1, 0]
output_row is [1, 1, 0]
---
###
empty_array is [1, 1, 0]
output_row is [1, 1, 0]
---
###
empty_array is [1, 1, 1]
output_row is [1, 1, 1]
---
# INCORRECT output IS
=> [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]
# SHOULD BE
=> [[1, 0, 0], [1, 0, 0], [0, 1, 0], [0, 1, 0], [0, 0, 1], [0, 0, 1]]
But if the empty array is defined within the block and assigned to a new variable it works as expected.
docs.each do |doc|
empty_array = Array.new(klas.size) { 0 } # THIS MAKES SURE empty_array stays with zero values
output_row = empty_array
output_row[klas.index(doc[1])] = 1
output << output_row
end
CORRECT output IS
=> [[1, 0, 0], [1, 0, 0], [0, 1, 0], [0, 1, 0], [0, 0, 1], [0, 0, 1]]
Why is the empty array modifying its value when it is outside a block? Shouldn't it remain the same irrespective of another array changing its value?