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
- Host: GitHub
- URL: https://github.com/dkubb/equalizer
- Owner: dkubb
- License: mit
- Created: 2012-08-30T15:16:06.000Z (over 13 years ago)
- Default Branch: master
- Last Pushed: 2026-03-20T14:17:22.000Z (about 1 month ago)
- Last Synced: 2026-04-19T04:06:03.500Z (12 days ago)
- Language: Ruby
- Homepage:
- Size: 172 KB
- Stars: 202
- Watchers: 6
- Forks: 16
- Open Issues: 0
- Releases: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
README.md
Equalizer
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'sHashandSetuseeql?andhashtogether. Equalizer ensures
these methods stay consistent—objects that areeql?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 thatinspectonly shows equality attributes. Use
instance_variablesto 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
- Name: Dan Kubb
- Login: dkubb
- Email:
- Kind: user
- Description:
- Website:
- Location: Mission, BC, Canada
- Twitter: dkubb
- Company: Betterment
- Icon url: https://avatars.githubusercontent.com/u/133?v=4
- Repositories: 42
- Last ynced at: 2023-04-10T00:16:29.799Z
- Profile URL: https://github.com/dkubb
GitHub Events
Total
- Watch event: 1
- Issue comment event: 1
- Push event: 2
Last Year
- Issue comment event: 1
- Push event: 2
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 | 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:
- dio.jp: 1
- jsmf.net: 1
- seonic.net: 1
- schirp-dso.com: 1
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
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
- Total packages: 13
-
Total downloads:
- rubygems: 257,750,162 total
- Total docker downloads: 1,577,950,072
- Total dependent packages: 73 (may contain duplicates)
- Total dependent repositories: 20,583 (may contain duplicates)
- Total versions: 40
- Total maintainers: 4
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
- devtools >= 0 development
- bundler ~> 1.3, >= 1.3.5 development
- actions/checkout v4 composite
- ruby/setup-ruby v1 composite
- rubygems/configure-rubygems-credentials v1.0.0 composite
- actions/checkout v4 composite
- ruby/setup-ruby v1 composite
- actions/checkout v4 composite
- ruby/setup-ruby v1 composite
- actions/checkout v4 composite
- actions/upload-artifact v4 composite
- ruby/setup-ruby v1 composite
- actions/checkout v4 composite
- ruby/setup-ruby v1 composite
Score: 29.036866531213537