For a language that’s optimised for programmer happiness, Ruby doesn’t half make a mess of equality.

With four different types of equal — equal?, eql?, == and === — it’s hard to keep track of them all. The first (and the simplest) — equal? — is a straightforward yay or nay to an object being the same as another object. Here, ‘the same’ means the exact same object. No twins, no duplicates.

== and === are the same as equal? at the basic level, but many of Ruby’s own classes override them for syntactic sugar. For example, the RegExp class overrides === to match strings (similar to =~), which makes for some peachy-looking case statements (which use === to test for equality instead of ==).

eql? is almost the same but not quite. It’s used to determine if two objects refer to the same hash key, but considering the default hash key is an object’s ID, it’s effectively the same as equal?.

Of course this is Ruby — so you’re free to override anything and make an even bigger clusterfuck if you so wish.