Ваше второе решение может быть сокращено до arr2 = arr.map do |e| e.dup end
(если на самом деле вам не нужно поведение clone
, рекомендуется вместо него использовать dup
).
Кроме того, ваши два решения в основном являются стандартными решениями для глубокого копирования (хотя вторая версия имеет глубину только в один уровень (т. Е. Если вы используете ее для массива массивов строк, вы все равно можете изменять строки) )). На самом деле нет лучшего способа.
Edit: вот рекурсивный метод deep_dup, который работает с произвольно вложенными массивами:
class Array
def deep_dup
map {|x| x.deep_dup}
end
end
class Object
def deep_dup
dup
end
end
class Numeric
# We need this because number.dup throws an exception
# We also need the same definition for Symbol, TrueClass and FalseClass
def deep_dup
self
end
end
Возможно, вы также захотите определить deep_dup для других контейнеров (например, Hash), в противном случае вы все равно получите поверхностную копию для них.