Class: PaperTrailDiff::ArrayChange

Inherits:
Object
  • Object
show all
Defined in:
lib/paper_trail_diff/value_objects.rb,
sig/generated/paper_trail_diff/value_objects.rbs

Overview

A change to an array inside a value the database stores whole, reported by membership rather than by position.

Position would be the obvious thing to report and the wrong one: elements here carry no identity, so inserting at the front makes every later index look changed, and one insertion is described as several edits. Membership is answerable without claiming any pairing -- "gained "saturn v"" is true whether the array is a set, a queue, or a ranked list.

That leaves one case membership cannot see, so it is named rather than hidden: the same elements in a different order. reordered? says so.

An element that is itself a Hash or Array is reported whole. Saying which field of which object changed would require pairing before-elements with after-elements, and nothing in the value licenses that pairing.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(from:, to:) ⇒ ArrayChange

: (from: Array, to: Array) -> void

Parameters:

  • from: (Array[untyped])
  • to: (Array[untyped])


45
46
47
48
49
50
51
# File 'lib/paper_trail_diff/value_objects.rb', line 45

def initialize(from:, to:)
  @from = Support.immutable_copy(from)
  @to = Support.immutable_copy(to)
  @added = Support.immutable_copy(ArrayChange.surplus(to, from))
  @removed = Support.immutable_copy(ArrayChange.surplus(from, to))
  freeze
end

Instance Attribute Details

#addedArray[untyped] (readonly)

Signature:

  • Array[untyped]

Returns:

  • (Array[untyped])


41
42
43
# File 'lib/paper_trail_diff/value_objects.rb', line 41

def added
  @added
end

#fromArray[untyped] (readonly)

Signature:

  • Array[untyped]

Returns:

  • (Array[untyped])


39
40
41
# File 'lib/paper_trail_diff/value_objects.rb', line 39

def from
  @from
end

#removedArray[untyped] (readonly)

Signature:

  • Array[untyped]

Returns:

  • (Array[untyped])


42
43
44
# File 'lib/paper_trail_diff/value_objects.rb', line 42

def removed
  @removed
end

#toArray[untyped] (readonly)

Signature:

  • Array[untyped]

Returns:

  • (Array[untyped])


40
41
42
# File 'lib/paper_trail_diff/value_objects.rb', line 40

def to
  @to
end

Class Method Details

.surplus(left, right) ⇒ Array[untyped]

Elements of left with no counterpart left in right, matching by value and respecting duplicates, so ["a", "a"] -> ["a"] reports one removal rather than none. : (Array, Array) -> Array

Parameters:

  • (Array[untyped])
  • (Array[untyped])

Returns:

  • (Array[untyped])


57
58
59
60
61
62
63
# File 'lib/paper_trail_diff/value_objects.rb', line 57

def self.surplus(left, right)
  pool = right.dup
  left.reject do |item|
    index = pool.index(item)
    index ? pool.delete_at(index) || true : false
  end
end

Instance Method Details

#empty?Boolean

: () -> bool

Returns:

  • (Boolean)


73
74
75
# File 'lib/paper_trail_diff/value_objects.rb', line 73

def empty?
  from == to
end

#reordered?Boolean

Same elements, different sequence. Only meaningful for a change that was recorded at all, which this only is when the two sides differ. : () -> bool

Returns:

  • (Boolean)


68
69
70
# File 'lib/paper_trail_diff/value_objects.rb', line 68

def reordered?
  added.empty? && removed.empty?
end

#to_hHash[Symbol, untyped]

: () -> Hash[Symbol, untyped]

Returns:

  • (Hash[Symbol, untyped])


78
79
80
81
82
83
84
85
86
# File 'lib/paper_trail_diff/value_objects.rb', line 78

def to_h
  {
    from: Support.serialize(from),
    to: Support.serialize(to),
    added: Support.serialize(added),
    removed: Support.serialize(removed),
    reordered: reordered?
  }
end