Ответ 1
Я не уверен, почему в Ruby нет метода глубоких копий, но я попытаюсь сделать обоснованное предположение на основе информации, которую я смог найти (см. ссылки и цитаты ниже строки).
Судя по этой информации, я мог только предположить, что причина, по которой Ruby не имеет метода глубокой копии, состоит в том, что она очень редко необходима, и в тех немногих случаях, когда это действительно необходимо, существуют и другие, относительно простые способы достижения та же задача:
Как вы уже знаете, использование Marshal.dump
и Marshal.load
в настоящее время является рекомендуемым способом для этого. Это также подход, рекомендованный программированием Ruby (см. Выдержки ниже).
В качестве альтернативы в этих драгоценных камнях есть как минимум 3 доступных реализации: deep_cloneable
, deep_clone
и ruby_deep_clone
; первый из них является самым популярным.
Связанная информация
Здесь обсуждение в comp.lang.ruby, которое может пролить свет на это. Здесь другой ответ здесь с некоторыми связанными обсуждениями, но все это возвращается к использованию Marshal
.
Не было никаких упоминаний о глубоком копировании в Programming Ruby, но было несколько упоминаний в Язык программирования Ruby. Вот несколько связанных выдержек:
[...]
Другим использованием для
Marshal.dump
иMarshal.load
является создание глубоких копий объектов:def deepcopy(o) Marshal.load(Marshal.dump(o)) end
[...]
... двоичный формат, используемый
Marshal.dump
иMarshal.load
, равен версии, зависящие от версии, и более новые версии Ruby не гарантируются способный читать маршированные объекты, написанные более старыми версиями Ruby.[...]
Обратите внимание, что файлы и потоки ввода-вывода, а также метод и привязка объекты, слишком динамичны для сортировки; не было бы надежного способ восстановить их состояние.
[...]
Вместо того чтобы сделать защитную глубокую копию массива, просто позвоните
to_enum
на нем и передать результирующий счетчик вместо массива сам. По сути, вы создаете перечислимый, но неизменяемый прокси-сервер объект для вашего массива.