A summary of data about the Ruby ecosystem.

https://github.com/dkubb/equalizer

Define equality, equivalency and hash methods automatically
https://github.com/dkubb/equalizer

Keywords from Contributors

dry-rb rack activejob activerecord mvc rubocop rubygems rspec crash-reporting ruby-syntax

Last synced: about 16 hours ago
JSON representation

Repository metadata

Define equality, equivalency and hash methods automatically

README.md

Equalizer

Gem Version
Test
Quality
Documentation
Mutation Testing

Equalizer provides equality, equivalence, hashing, pattern matching, and
inspection methods for Ruby objects based on explicitly specified attributes.

Unlike approaches that automatically use all attr_reader attributes,
Equalizer requires explicit specification of which attributes affect equality,
giving you full control over comparison behavior.

Installation

Add this line to your application's Gemfile:

gem "equalizer"

Or install it directly:

gem install equalizer

Quick Start

class Point
  include Equalizer.new(:x, :y)

  attr_reader :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end
end

p1 = Point.new(1, 2)
p2 = Point.new(1, 2)

p1 == p2           # => true
p1.eql?(p2)        # => true
p1.hash == p2.hash # => true

Features

Selective Attribute Comparison

Only the attributes you specify are used for equality. Other instance variables
are ignored:

[!TIP]
This is useful when you have attributes that shouldn't affect equality, like
timestamps, cached values, or display names.

class GeoLocation
  include Equalizer.new(:latitude, :longitude)

  attr_reader :latitude, :longitude, :name

  def initialize(latitude, longitude, name = nil)
    @latitude = latitude
    @longitude = longitude
    @name = name
  end
end

home = GeoLocation.new(37.7786, -122.4407, "Home")
work = GeoLocation.new(37.7786, -122.4407, "Work")

home == work  # => true (name is not part of equality)

Equality vs Equivalence

Equalizer provides two comparison methods with different semantics:

== (Equality)

Returns true if the other object is an instance of the same class or a
subclass
, and all specified attributes are equal using ==:

class ColoredPoint < Point
  attr_reader :color

  def initialize(x, y, color)
    super(x, y)
    @color = color
  end
end

point = Point.new(1, 2)
colored = ColoredPoint.new(1, 2, "red")

point == colored   # => true (ColoredPoint is a subclass of Point)
colored == point   # => false (Point is not a subclass of ColoredPoint)

[!IMPORTANT]
In Ruby, the == operator is asymmetric when comparing across class
hierarchies. A parent class instance can equal a subclass instance, but not
vice versa.

eql? (Equivalence)

Returns true only if both objects are instances of the exact same class,
and all specified attributes are equal using eql?:

point = Point.new(1, 2)
colored = ColoredPoint.new(1, 2, "red")

point.eql?(colored)   # => false (different classes)
colored.eql?(point)   # => false (different classes)

point.eql?(Point.new(1, 2))  # => true (same class, same values)

Hashing

Objects that are eql? will have the same hash code, making them safe for use
as Hash keys and in Sets:

[!NOTE]
Ruby's Hash and Set use eql? and hash together. Equalizer ensures
these methods stay consistent—objects that are eql? always have matching
hash codes.

require "set"

p1 = Point.new(1, 2)
p2 = Point.new(1, 2)

# As Hash keys
locations = {}
locations[p1] = "first"
locations[p2] = "second"
locations.size  # => 1 (p1 and p2 are the same key)

# In Sets
set = Set.new
set << p1
set << p2
set.size  # => 1

Pattern Matching

Equalizer provides full support for Ruby's pattern matching syntax.

[!TIP]
Use array patterns [x, y] for positional matching when attribute order
matters. Use hash patterns {x:, y:} for named matching when you want
clarity or only need specific attributes.

Array Patterns

Use deconstruct for array-style pattern matching:

point = Point.new(3, 4)

case point
in [0, 0]
  puts "origin"
in [x, 0]
  puts "on x-axis at #{x}"
in [0, y]
  puts "on y-axis at #{y}"
in [x, y]
  puts "at (#{x}, #{y})"
end
# => "at (3, 4)"

Hash Patterns

Use deconstruct_keys for hash-style pattern matching:

point = Point.new(3, 4)

case point
in { x: 0, y: 0 }
  puts "origin"
in { x:, y: } if x == y
  puts "on diagonal at #{x}"
in { x:, y: }
  puts "at (#{x}, #{y})"
end
# => "at (3, 4)"

Class Patterns

Combine with class checks:

case point
in Point(x: 0, y: 0)
  puts "origin point"
in Point(x:, y:)
  puts "point at (#{x}, #{y})"
end

Clean Inspect Output

Equalizer customizes inspect to show only the attributes used for equality:

class User
  include Equalizer.new(:id)

  attr_reader :id, :name, :email, :created_at

  def initialize(id, name, email)
    @id = id
    @name = name
    @email = email
    @created_at = Time.now
  end
end

user = User.new(42, "Alice", "alice@example.com")
user.inspect
# => "#<User:0x00007f... @id=42>"
# Note: name, email, and created_at are not shown

[!NOTE]
When debugging, remember that inspect only shows equality attributes. Use
instance_variables to see all instance variables if needed.

To keep the original inspect and pretty_print methods, pass inspect: false:

class Person < Struct.new(:id, :name)
  include Equalizer.new(:id, inspect: false)
end

amy = Person.new(1, "Amy")
amy.inspect
# => "#<struct Person id=1, name=\"Amy\">"

Clean Ancestor Chain

The included module has a descriptive name in the ancestor chain:

Point.ancestors
# => [Point, Equalizer(x, y), Object, Kernel, BasicObject]

Nested Equalizer Objects

Equalizer objects can be nested and will compare correctly:

class Line
  include Equalizer.new(:start_point, :end_point)

  attr_reader :start_point, :end_point

  def initialize(start_point, end_point)
    @start_point = start_point
    @end_point = end_point
  end
end

line1 = Line.new(Point.new(0, 0), Point.new(1, 1))
line2 = Line.new(Point.new(0, 0), Point.new(1, 1))

line1 == line2  # => true

Error Handling

[!CAUTION]
Equalizer validates arguments at include time. Errors will be raised
immediately if you pass invalid arguments.

Equalizer validates its arguments:

# At least one attribute is required
Equalizer.new()
# => ArgumentError: at least one attribute is required

# Attributes must be Symbols
Equalizer.new("name")
# => ArgumentError: attribute must be a Symbol, got String

Supported Ruby Versions

This library aims to support and is tested against the following Ruby
implementations:

  • Ruby 3.3
  • Ruby 3.4
  • Ruby 4.0

If something doesn't work on one of these versions, it's a bug.

This library may inadvertently work (or seem to work) on other Ruby versions or
implementations, however support will only be provided for the implementations
listed above.

If you would like this library to support another Ruby version or
implementation, you may volunteer to be a maintainer. Being a maintainer
entails making sure all tests run and pass on that implementation. When
something breaks on your implementation, you will be responsible for providing
patches in a timely fashion. If critical issues for a particular implementation
exist at the time of a major release, support for that Ruby version may be
dropped.

Credits

License

The gem is available as open source under the terms of the MIT License.


Owner metadata


GitHub Events

Total
Last Year

Committers metadata

Last synced: 4 days ago

Total Commits: 206
Total Committers: 11
Avg Commits per committer: 18.727
Development Distribution Score (DDS): 0.583

Commits in past year: 3
Committers in past year: 1
Avg Commits per committer in past year: 3.0
Development Distribution Score (DDS) in past year: 0.0

Name Email Commits
Dan Kubb d****b@g****m 86
Erik Michaels-Ober s****k@g****m 75
Markus Schirp m****j@s****m 20
Markus Schirp m****j@s****t 14
snusnu g****a@g****m 2
Piotr Solnica p****a@g****m 2
Myron Marston m****n@g****m 2
Anatoly Chernow f****e@g****m 2
Jan Suchal j****o@j****t 1
Craig Little c****l@g****m 1
Akira Matsuda r****e@d****p 1

Committer domains:


Issue and Pull Request metadata

Last synced: 8 days ago

Total issues: 10
Total pull requests: 22
Average time to close issues: about 3 years
Average time to close pull requests: 10 months
Total issue authors: 8
Total pull request authors: 12
Average comments per issue: 4.2
Average comments per pull request: 3.0
Merged pull request: 16
Bot issues: 0
Bot pull requests: 0

Past year issues: 0
Past year pull requests: 0
Past year average time to close issues: N/A
Past year average time to close pull requests: N/A
Past year issue authors: 0
Past year pull request authors: 0
Past year average comments per issue: 0
Past year average comments per pull request: 0
Past year merged pull request: 0
Past year bot issues: 0
Past year bot pull requests: 0

More stats: https://issues.ecosyste.ms/repositories/lookup?url=https://github.com/dkubb/equalizer

Top Issue Authors

  • solnic (3)
  • backus (1)
  • ch1c0t (1)
  • cbandy (1)
  • phurni (1)
  • botandrose (1)
  • sferik (1)
  • jsuchal (1)

Top Pull Request Authors

  • ch1c0t (4)
  • sferik (4)
  • mbj (3)
  • dkubb (2)
  • amatsuda (2)
  • ck3g (1)
  • craiglittle (1)
  • solnic (1)
  • markprzepiora (1)
  • jsuchal (1)
  • myronmarston (1)
  • snusnu (1)

Top Issue Labels

  • question (1)

Top Pull Request Labels

  • enhancement (2)

Package metadata

gem.coop: equalizer

Equalizer provides a simple way to define equality (==), equivalence (eql?), and hashing (hash) methods for Ruby objects based on specified attributes. Includes pattern matching support and clean inspect output.

  • Homepage: https://github.com/dkubb/equalizer
  • Documentation: http://www.rubydoc.info/gems/equalizer/
  • Licenses: MIT
  • Latest release: 1.0.0 (published about 1 month ago)
  • Last Synced: 2026-04-28T12:23:16.739Z (3 days ago)
  • Versions: 11
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 128,886,803 Total
  • Docker Downloads: 788,975,036
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 0.076%
    • Docker downloads count: 0.119%
    • Downloads: 0.187%
  • Maintainers (4)
rubygems.org: equalizer

Equalizer provides a simple way to define equality (==), equivalence (eql?), and hashing (hash) methods for Ruby objects based on specified attributes. Includes pattern matching support and clean inspect output.

  • Homepage: https://github.com/dkubb/equalizer
  • Documentation: http://www.rubydoc.info/gems/equalizer/
  • Licenses: MIT
  • Latest release: 1.0.0 (published about 1 month ago)
  • Last Synced: 2026-04-27T15:03:11.299Z (4 days ago)
  • Versions: 11
  • Dependent Packages: 73
  • Dependent Repositories: 20,583
  • Downloads: 128,863,359 Total
  • Docker Downloads: 788,975,036
  • Rankings:
    • Docker downloads count: 0.139%
    • Downloads: 0.149%
    • Dependent repos count: 0.25%
    • Dependent packages count: 0.396%
    • Average: 2.016%
    • Stargazers count: 4.001%
    • Forks count: 7.159%
  • Maintainers (4)
proxy.golang.org: github.com/dkubb/equalizer

  • Homepage:
  • Documentation: https://pkg.go.dev/github.com/dkubb/equalizer#section-documentation
  • Licenses: mit
  • Latest release: v1.0.0 (published about 1 month ago)
  • Last Synced: 2026-04-27T15:02:49.848Z (4 days ago)
  • Versions: 8
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Stargazers count: 3.537%
    • Forks count: 5.453%
    • Average: 7.342%
    • Dependent packages count: 9.576%
    • Dependent repos count: 10.802%
debian-10: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Documentation: https://packages.debian.org/buster/ruby-equalizer
  • Licenses:
  • Latest release: 0.0.11-2 (published 3 months ago)
  • Last Synced: 2026-03-13T05:01:02.405Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
ubuntu-24.04: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Licenses:
  • Latest release: 0.0.11-2 (published 3 months ago)
  • Last Synced: 2026-03-06T15:58:19.102Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
ubuntu-23.04: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Licenses:
  • Latest release: 0.0.11-2 (published 3 months ago)
  • Last Synced: 2026-03-11T14:11:22.839Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
ubuntu-20.04: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Licenses:
  • Latest release: 0.0.11-2 (published 3 months ago)
  • Last Synced: 2026-03-13T13:27:13.448Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
ubuntu-23.10: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Licenses:
  • Latest release: 0.0.11-2 (published 3 months ago)
  • Last Synced: 2026-03-14T02:20:34.849Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
debian-11: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Documentation: https://packages.debian.org/bullseye/ruby-equalizer
  • Licenses:
  • Latest release: 0.0.11-2 (published 3 months ago)
  • Last Synced: 2026-03-14T06:22:32.895Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
debian-12: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Documentation: https://packages.debian.org/bookworm/ruby-equalizer
  • Licenses:
  • Latest release: 0.0.11-2 (published 3 months ago)
  • Last Synced: 2026-03-13T15:47:10.490Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
ubuntu-24.10: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Licenses:
  • Latest release: 0.0.11-2 (published 3 months ago)
  • Last Synced: 2026-03-09T17:05:09.483Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
ubuntu-22.04: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Licenses:
  • Latest release: 0.0.11-2 (published 3 months ago)
  • Last Synced: 2026-03-13T22:41:54.414Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
debian-13: ruby-equalizer

  • Homepage: https://github.com/dkubb/equalizer
  • Documentation: https://packages.debian.org/trixie/ruby-equalizer
  • Licenses:
  • Latest release: 0.0.11-3 (published 3 months ago)
  • Last Synced: 2026-03-14T18:07:55.946Z (about 2 months ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%

Dependencies

Gemfile rubygems
  • devtools >= 0 development
equalizer.gemspec rubygems
  • bundler ~> 1.3, >= 1.3.5 development
.github/workflows/push.yml actions
  • actions/checkout v4 composite
  • ruby/setup-ruby v1 composite
  • rubygems/configure-rubygems-credentials v1.0.0 composite
.github/workflows/quality.yml actions
  • actions/checkout v4 composite
  • ruby/setup-ruby v1 composite
.github/workflows/test.yml actions
  • actions/checkout v4 composite
  • ruby/setup-ruby v1 composite
.github/workflows/yard.yml actions
  • actions/checkout v4 composite
  • actions/upload-artifact v4 composite
  • ruby/setup-ruby v1 composite
.github/workflows/mutant.yml actions
  • actions/checkout v4 composite
  • ruby/setup-ruby v1 composite

Score: 29.036866531213537