The MismatchInspectable
module provides a way to compare two objects and find the differences in their attributes. The module can be included in any class to compare objects of that class, and it provides options for the output format, recursion, and inclusion of class names in the output.
Usage
To use MismatchInspectable
, first include it in your class and list the attributes you want to compare using the inspect_mismatch_for
method.
class Thing
include MismatchInspectable
inspect_mismatch_for :color, :shape, :is_cool
def initialize(color, shape, is_cool)
@color = color
@shape = shape
@is_cool = is_cool
end
end
Then, to compare two objects of the class, call the inspect_mismatch method on one of the objects and pass the other object as an argument.
thing1 = Thing.new("red", "circle", true)
thing2 = Thing.new("blue", "circle", false)
mismatch = thing1.inspect_mismatch(thing2)
Options
format
You can choose from three different output formats: :array, :hash, or :object. The default format is :array.
• :array format example:
[
['Thing#color', 'red', 'blue'],
['Thing#is_cool', true, false]
]
• :hash format example:
{
'Thing#color' => ['red', 'blue'],
'Thing#is_cool' => [true, false]
}
:object format example:
{
Thing: {
color: ['red', 'blue'],
is_cool: [true, false]
}
}
include_class (default: true)
When this option is set to true, the comparison will include the class in the
output for the objects being compared. If the objects being compared have
different classes, a mismatch will always be reported, regardless of this flag
being set. If set to false, you will simply not see the class names in the
output.
recursive (default: false)
When this option is set to true, the comparison will be performed recursively on
all instance variables which are passed to inspect_mismatch_for
. If any of the
instance variables are also objects that include the MismatchInspectable
module, their inspect_mismatch
method will be called with the same options. If
set to false,the comparison will only be performed on the top-level instance
variables which are passed to inspect_mismatch_for
and will not delve deeper
into the objects. Instead it will do a simple comparison of said instance
variables.
Examples
Example 1: Basic usage
require "mismatch_inspectable"
class Car
include MismatchInspectable
inspect_mismatch_for :make, :model, :year
def initialize(make, model, year)
@make = make
@model = model
@year = year
end
attr_accessor :make, :model, :year
end
car1 = Car.new("Toyota", "Camry", 2020)
car2 = Car.new("Toyota", "Corolla", 2020)
mismatches = car1.inspect_mismatch(car2)
Example 2: Using different formats
mismatches_hash = car1.inspect_mismatch(car2, format: :hash)
mismatches_object = car1.inspect_mismatch(car2, format: :object)
Example 3: Comparing nested objects
class Owner
include MismatchInspectable
inspect_mismatch_for :name, :age
def initialize(name, age)
@name = name
@age = age
end
attr_accessor :name, :age
end
class Pet
include MismatchInspectable
inspect_mismatch_for :name, :species, :owner
def initialize(name, species, owner)
@name = name
@species = species
@owner = owner
end
attr_accessor :name, :species, :owner
end
owner1 = Owner.new("Alice", 30)
owner2 = Owner.new("Bob", 35)
pet1 = Pet.new("Fluffy", "cat", owner1)
pet2 = Pet.new("Fluffy", "cat", owner2)
mismatches = pet1.inspect_mismatch(pet2, recursive: true)
Example 4: Excluding class from output
mismatches_no_class = pet1.inspect_mismatch(pet2, recursive: true, include_class: false)
Example 5: Comparing objects with recursive set to false
pet5 = Pet.new("Max", "dog", owner1)
pet6 = Pet.new("Max", "dog", owner2)
mismatches_non_recursive = pet5.inspect_mismatch(pet6, recursive: false)
Example 6: Comparing objects when one is null
owner3 = Owner.new("Charlie", 40)
pet3 = Pet.new("Buddy", "dog", owner3)
pet4 = Pet.new("Buddy", "dog", nil)
mismatches_owner_nil = pet3.inspect_mismatch(pet4, recursive: true)