Module: IS::Deep

Included in:
Array, Hash
Defined in:
lib/is-deep/core.rb,
lib/is-deep/info.rb

Overview

Deep merge functionality for Ruby collections.

This module provides deep merge, deep duplication, and configurable array merge strategies for Hash and Array classes.

Examples:

Basic usage

{ a: 1 }.deep_merge({ b: 2 }) # => { a: 1, b: 2 }
{ x: [1] }.deep_merge({ x: [2] }) # => { x: [1, 2] } (with concat strategy)

Custom array strategy

IS::Deep.array_strategy = IS::Deep::ArrayStrategies::REPLACE
{ x: [1] }.deep_merge({ x: [2] }) # => { x: [2] }

Defined Under Namespace

Modules: ArrayStrategies, Info

Class Attribute Summary collapse

Instance Method Summary collapse

Class Attribute Details

.array_strategy#call

The current array merge strategy.

The strategy is thread-local. If not set for current thread, falls back to global default.

Returns:

  • (#call)

    Callable object accepting (base, other) arguments

See Also:



30
31
32
# File 'lib/is-deep/core.rb', line 30

def array_strategy
  Thread.current[:is_deep_array_strategy] || @default_array_strategy
end

Instance Method Details

#deep_merge(other, array_strategy: nil) ⇒ IS::Deep

Performs deep merge on a duplicate of the receiver.

Creates a deep copy of self, then merges other into it. Non-destructive operation — original receiver is not modified.

Examples:

base = { a: { b: 1 } }
base.deep_merge({ a: { c: 2 } }) # => { a: { b: 1, c: 2 } }
base # => { a: { b: 1 } } (unchanged)

Parameters:

  • other (Object)

    Object to merge into self

  • array_strategy (#call, nil) (defaults to: nil)

    Optional override for array merge strategy

Returns:

  • (IS::Deep)

    New object containing merged data



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/is-deep/core.rb', line 56

def deep_merge other, array_strategy: nil
  base = if self.respond_to?(:deep_dup)
      self.deep_dup
    elsif self.respond_to?(:dup)
      self.dup
    else
      self
    end
  if base.respond_to?(:deep_merge!)
    base.deep_merge! other, array_strategy: array_strategy
  elsif base.respond_to?(:merge)
    base.merge other
  elsif base.respond_to?(:merge!)
    base.merge! other
  else
    raise NoMethodError, "No merge methods in receiver (#{base.class})", caller_locations
  end
end