When you made a duplicate of your array, you ended up with two separate arrays that had the same elements in them, like in this example:
x = [1, 2, 3]
y = [1, 2, 3]
x << 4
p x
p y
--output:--
[1, 2, 3, 4]
[1, 2, 3]
You wouldn't expect changes to the x array to affect the y array, would you? Similarly:
arr = [1, 2, 3]
puts "arr = #{arr}" #arr = [1, 2, 3
copy = arr.dup
puts "copy = #{copy}" #copy = [1, 2, 3]
arr << 4
puts "arr = #{arr}" #arr = [1, 2, 3, 4]
puts "copy = #{copy}" #copy = [1, 2, 3]
copy << "hello"
puts "arr = #{arr}" #arr = [1, 2, 3, 4]
puts "copy = #{copy}" #copy = [1, 2, 3, "hello"]
In that example, arr plays the role of self, and copy plays the role of self.dup. The arrays self and self.dup are different arrays which happen to have the same elements.
An array can have an unlimited number of variables that refer to it:
arr = [1, 2, 3]
puts "arr = #{arr}" #arr = [1, 2, 3]
input = arr
input << 4
puts "arr = #{arr}" #arr = [1, 2, 3, 4]
Now let's make input refer to another array:
copy = arr.dup
input = copy
input << "hello"
puts "copy = #{copy}" #copy = [1, 2, 3, 4, "hello"]
puts "input = #{input}" #input = [1, 2, 3, 4, "hello"]
puts "arr = #{arr}" #arr = [1, 2, 3, 4]