Я пытаюсь изменить копию массива без изменения исходного массива. Это массив хэшей, так, чтобы сделать «все новое» копию массива я использую:Почему действие << b действует иначе, чем a = a + b (с скопированным массивом хэшей со строками)
foo = [ { :a => "aaaaaa" } ]
foocopy = foo.map { |h| h.dup }
Я хочу добавить некоторые данные в виде строки в хэш в копии.
Он отлично работает, если я использую =
и +
:
foocopy.first[:a] = foocopy.first[:a] + "bbbbb"
foo
=> [{:a=>"aaaaaa"}] # original unchanged as expected
foocopy
=> [{:a=>"aaaaaabbbbb"}]
Однако, если я использую <<
это модифицированный ОБА копию и оригинал:
foocopy.first[:a] << "cccccc"
foo
=> [{:a=>"aaaaaacccccc"}] # ORIGINAL got changed too
foocopy
=> [{:a=>"aaaaaacccccc"}]
Это ошибка в Ruby?
Это очень * очень маловероятно, что вы найдете ошибку в хорошо избитых вещах, таких как '<<' и '+' при работе с массивами. –
И все же ... это происходит ... http://stackoverflow.com/questions/29224421/rails-3-2-saving-serialized-hash-will-not-save-number-with-delimiter, который до любой, кто взвесил, кажется, является ошибкой рельсов, которая сохраняется до 4. В этом случае из-за конкретного случая (изменение строки внутри хэша внутри скопированного массива) казалось правдоподобным быть ошибкой. Но объяснение, данное @jorge, было поучительным. Моя точка зрения, хотя и маловероятна, это не невозможно, и AFAIK SO - довольно хорошее место, чтобы спросить и узнать. – jpwynn
Рельсы - это едва ли тот же слой, что и Ruby, а '<<' и '+' используются чрезмерно в несколько раз больше, чем метод Rails *, любой метод * Rails. Таким образом, поиск ошибки в Rails гораздо более вероятен, чем основной метод в Ruby. –