From 3cccf891c90f6269099d02d6988a191ba03c1735 Mon Sep 17 00:00:00 2001 From: nick evans Date: Sat, 29 Aug 2026 17:13:23 -0400 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Match=20subclasses=20in=20?= =?UTF-8?q?`SearchResult#eql=3F`/`#hash`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copying the behavior of `Array#eql?` and `Array#hash`, this updates both `SearchResult#eql?` and `SearchResult#hash` to match explicitly on `SearchResult` rather than the specific `self.class`. This way, they also match subclass instances (assuming the subclass doesn't override these methods). `#hash` was also re-ordered to match `#eql?`. This isn't needed for performance. It just makes it a little bit easier to identify that the two methods are comparing the same properties. --- lib/net/imap/search_result.rb | 4 ++-- test/net/imap/test_search_result.rb | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/net/imap/search_result.rb b/lib/net/imap/search_result.rb index c53de15b..2470db91 100644 --- a/lib/net/imap/search_result.rb +++ b/lib/net/imap/search_result.rb @@ -73,11 +73,11 @@ def ==(other) end # Hash equality. Unlike #==, order will be taken into account. - def hash = [super, self.class, modseq].hash + def hash = [SearchResult, modseq, super].hash # Hash equality. Unlike #==, order will be taken into account. def eql?(other) - self.class == other.class && + SearchResult === other && modseq == other.modseq && super end diff --git a/test/net/imap/test_search_result.rb b/test/net/imap/test_search_result.rb index aeec602c..871cca12 100644 --- a/test/net/imap/test_search_result.rb +++ b/test/net/imap/test_search_result.rb @@ -93,6 +93,22 @@ class SearchDataTests < Net::IMAP::TestCase refute_operator result.hash, :eql?, array.hash end + # NOTE: this subclass is NOT overriding #==, #hash, or #eql? + Subclass = Class.new(SearchResult) + + test "SearchResult[...] == / eql? Subclass[...]" do + array = [1, 5, 20, 3, 98] + result = SearchResult[*array] + subclass = Subclass[*array] + assert_operator result, :eql?, subclass + assert_equal result.hash, subclass.hash + modseq = 12345 + result = SearchResult[*array, modseq:] + subclass = Subclass[*array, modseq:] + assert_operator result, :eql?, subclass + assert_equal result.hash, subclass.hash + end + test "SearchResult[*nz_numbers, modseq: nz_number] != / not eql? Array[*nz_numbers]" do array = [1, 5, 20, 3, 98] result = SearchResult[*array, modseq: 123456]