Module: Lutaml::Model::ComparableModel

Included in:
Serialize
Defined in:
lib/lutaml/model/comparable_model.rb

Overview

ComparableModel module provides functionality to compare and diff two objects of the same class, based on their attribute values.

Defined Under Namespace

Modules: ClassMethods, StructuralDiff Classes: DiffContext, Tree

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



8
9
10
# File 'lib/lutaml/model/comparable_model.rb', line 8

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#already_compared?(other, compared_objects) ⇒ Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/lutaml/model/comparable_model.rb', line 69

def already_compared?(other, compared_objects)
  compared_objects[comparison_key(other)]
end

#attributes_hash(processed_objects) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/lutaml/model/comparable_model.rb', line 86

def attributes_hash(processed_objects)
  self.class.attributes.map do |attr, _|
    attr_value = public_send(attr)

    if attr_value.is_a?(ComparableModel)
      attr_value.calculate_hash(processed_objects)
    else
      attr_value.hash
    end
  end
end

#calculate_hash(processed_objects = {}.compare_by_identity) ⇒ Object



79
80
81
82
83
84
# File 'lib/lutaml/model/comparable_model.rb', line 79

def calculate_hash(processed_objects = {}.compare_by_identity)
  return if processed_objects.key?(self)

  processed_objects[self] = true
  ([self.class] + attributes_hash(processed_objects)).hash
end

#comparison_key(other) ⇒ Object



65
66
67
# File 'lib/lutaml/model/comparable_model.rb', line 65

def comparison_key(other)
  "#{object_id}:#{other.object_id}"
end

#diff(other) ⇒ Array<Hash>

Structured diff (lutaml-model#18): returns one entry per differing attribute path, recursively through nested models and collections. Equal objects diff to [].

Parameters:

  • other (Object)

    the object to diff against

Returns:

  • (Array<Hash>)

    [{ path:, left:, right: }] entries



57
58
59
# File 'lib/lutaml/model/comparable_model.rb', line 57

def diff(other)
  Lutaml::Model::ComparableModel::StructuralDiff.diff(self, other)
end

#eql?(other, compared_objects = {}) ⇒ Boolean Also known as: ==

Checks if two objects are equal based on their attributes

Parameters:

  • other (Object)

    The object to compare with

Returns:

  • (Boolean)

    True if objects are equal, false otherwise



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/lutaml/model/comparable_model.rb', line 15

def eql?(other, compared_objects = {})
  return true if equal?(other)
  return false unless same_class?(other)
  return true if already_compared?(other, compared_objects)

  compared_objects[comparison_key(other)] = true
  self.class.attributes.all? do |attr, _|
    attr_value = public_send(attr)
    other_value = other.public_send(attr)

    if attr_value.is_a?(ComparableModel) && same_class?(attr_value)
      attr_value.eql?(other_value, compared_objects)
    else
      attr_value == other_value
    end
  end
end

#hashInteger

Generates a hash value for the object

Returns:

  • (Integer)

    The hash value



75
76
77
# File 'lib/lutaml/model/comparable_model.rb', line 75

def hash
  calculate_hash
end

#same_as?(other, ignore_element_order: true) ⇒ Boolean

Order-insensitive equality (lutaml-model#17): collection attributes compare as multisets — document order within a collection does not affect the result. Non-collection attributes and nested models keep strict equality.

Parameters:

  • other (Object)

    the object to compare with

  • ignore_element_order (Boolean) (defaults to: true)

    compare collections order-insensitively

Returns:

  • (Boolean)


44
45
46
47
48
49
# File 'lib/lutaml/model/comparable_model.rb', line 44

def same_as?(other, ignore_element_order: true)
  return true if equal?(other)
  return false unless instance_of?(other.class)

  unordered_eql?(self, other, {}, ignore_element_order)
end

#same_class?(other) ⇒ Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/lutaml/model/comparable_model.rb', line 61

def same_class?(other)
  other.instance_of?(self.class)
end