user3719047
user3719047

Reputation: 39

Original variable still changes with .clone or .dup

When I execute this program, the original_couples list and the new_couples list are always the same. I thought using .clone or .dup was supposed to be a way of copying without changes being made to the original variable. So why is it happening here?

def swingers(couples)

    original_couples = couples

    new_couples = original_couples.clone

    swap_index1 = rand(3)
    swap_index2 = rand(3)

    new_couples[swap_index1][0], new_couples[swap_index2][0] = new_couples[swap_index2]    [0], new_couples[swap_index1][0] 

    puts original_couples
    puts new_couples
end
swingers([
  ["Clyde", "Bonnie"],
  ["Paris", "Helen"],
  ["Romeo", "Juliet"]
])  

Upvotes: 1

Views: 276

Answers (1)

Renato Zannon
Renato Zannon

Reputation: 29951

A dup or clone in Ruby is a shallow clone, meaning that only the outer object is cloned, not its children. In your case, this means that the couples array is copied, but not each individual couple.

If you want it to be a deep clone, you need to do it manually for the stdlib arrays:

new_couples = original_couples.map { |couple| couple.clone }

If you are in a domain where copies of collections are often necessary, or you are trying to work in a more functional style, I suggest you take a look at the Hamster gem, that brings immutable data structures to ruby.

Upvotes: 1

Related Questions