Not so much philosophical today, so here’s something useful.
In Ruby, arguments are passed by reference, and using obj.clone / obj.dup may cause major headaches trying to figure out why your duplicated nested array is being changed while it shouldn’t.
a = [["my elements are"], ["here"]]
b = a.dup
p a # => [["my elements are"], ["here"]]
p b # => [["my elements are"], ["here"]]
b[1][0] = "not here"
# where did my elements go?
p a # => [["my elements are"], ["not here"]]
p b # => [["my elements are"], ["not here"]]
Why isn’t it duplicated? It actually is, the first array is duplicated, but the nested elements are still references. A way to force everything to be duplicated for sure is to use Marshal library.
a = [["my elements are"], ["here"]]
b = Marshal.load(Marshal.dump(a))
p a # => [["my elements are"], ["here"]]
p b # => [["my elements are"], ["here"]]
b[1][0] = "not here"
# Look! They're here!
p a # => [["my elements are"], ["here"]]
p b # => [["my elements are"], ["not here"]]
comments powered by Disqus