Consider the following Ruby code:
a = ["x"] * 3 # or a = Array.new(3, "x")
a[0].insert(0, "a")
a.each {|i| puts i}
I would expect the output to be ax, x, x (on new lines of course). However, with Ruby 1.9.1 the output is ax, ax, ax. What’s going on? I’ve narrowed the problem down to the way the array a is defined. If I explicitly write out
a = ["x", "x", "x"]
then the code works as expected, but either version in the original code gives me this unexpected behaviour. It appears that the */initializer means the copies are actually references to the same copy of the string “x”. However, if instead of the insert command I write
a[0] = "a" + a[0]
Then I get the desired output. Is this a bug, or is there some feature at work which I’m not understanding?
The documentation to Array.new(size=0, obj=nil):
and Array * int:
So in both of the forms you’re surprised by, you end up with three references to the same
"x"object, just as you figured out. I’d say you might argue about the design decision, but it’s a documented intentional behavior, not a bug.The best way I know to get the behavior you want without manually writing the array literal (
["x", "x", "x"]) isOr course, with just three elements, it doesn’t much matter, but with anything much bigger, this form comes in handy.