Sha256: 28cdba2ba06bf0052622f7530e169c39697ab13e6f0a8d2a86b083ca6a6a4f21

Contents?: true

Size: 900 Bytes

Versions: 10

Compression:

Stored size: 900 Bytes

Contents

require 'set'
class RecursiveOpenStruct::DeepDup
  def initialize(opts={})
    @recurse_over_arrays = opts.fetch(:recurse_over_arrays, false)
    @preserve_original_keys = opts.fetch(:preserve_original_keys, false)
  end

  def call(obj)
    deep_dup(obj)
  end

  private

  def deep_dup(obj, visited=Set.new)
    if obj.is_a?(Hash)
      obj.each_with_object({}) do |(key, value), h|
        h[@preserve_original_keys ? key : key.to_sym] = value_or_deep_dup(value, visited)
      end
    elsif obj.is_a?(Array) && @recurse_over_arrays
      obj.each_with_object([]) do |value, arr|
        value = value.is_a?(RecursiveOpenStruct) ? value.to_h : value
        arr << value_or_deep_dup(value, visited)
      end
    else
      obj
    end
  end

  def value_or_deep_dup(value, visited)
    obj_id = value.object_id
    visited.include?(obj_id) ? value : deep_dup(value, visited << obj_id)
  end
end

Version data entries

10 entries across 10 versions & 1 rubygems

Version Path
recursive-open-struct-2.0.0 lib/recursive_open_struct/deep_dup.rb
recursive-open-struct-1.3.1 lib/recursive_open_struct/deep_dup.rb
recursive-open-struct-1.3.0 lib/recursive_open_struct/deep_dup.rb
recursive-open-struct-1.2.2 lib/recursive_open_struct/deep_dup.rb
recursive-open-struct-1.1.3 lib/recursive_open_struct/deep_dup.rb
recursive-open-struct-1.1.2 lib/recursive_open_struct/deep_dup.rb
recursive-open-struct-1.1.1 lib/recursive_open_struct/deep_dup.rb
recursive-open-struct-1.1.0 lib/recursive_open_struct/deep_dup.rb
recursive-open-struct-1.0.5 lib/recursive_open_struct/deep_dup.rb
recursive-open-struct-1.0.4 lib/recursive_open_struct/deep_dup.rb