Equality of identical objects
A feature I pretty much take for granted after years of working with Ruby is that two identical basic objects are considered equal:
{ key1: "value1", key2: "value2" } == { key1: "value1", key2: "value2" }
# => true
[1, 2, 3] == [1, 2, 3]
# => true
{ key1: "value1", key2: "value2" } == { key1: "value1", key2: "value2" }
// => false
[1, 2, 3] == [1, 2, 3]
// => false
Note that this works even for deeply nested data structures. In JavaScript (Node.js), we would have to reach for something like isDeepStrictEqual from the util module to get the same behavior.
Ruby's Struct and Data classes behave the same:
PersonStruct = Struct.new(:name)
PersonStruct.new("Alice") == PersonStruct.new("Alice")
# => true
PersonData = Data.define(:name)
PersonData.new("Bob") == PersonData.new("Bob")
# => true
If we wanted comparison to behave like in JavaScript and many other languages (that is, to confirm that we're comparing the same object in memory rather than an object with the same values), we can use #equal? instead of #==:
hash1 = { key1: "value1", key2: "value2" }
hash2 = { key1: "value1", key2: "value2" }
hash1.equal?(hash2) # => false
hash1.equal?(hash1) # => true
I have personally never had a use case for #equal? in my code, but the more you know!
History
This behavior of == has been around since Ruby's inception.
It was likely inspired by Smalltalk, which provides two methods for comparison: = for value equality and == for identity (object) equality. In Ruby, the == method is used for value equality, while the equal? method is used for identity (object) equality.