From 3f36e0b4e37b66543117af389d3634e47bda85b4 Mon Sep 17 00:00:00 2001 From: nick evans Date: Fri, 2 Oct 2026 19:24:54 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9A=EF=B8=8F=20Improve=20rdoc=20for=20?= =?UTF-8?q?`SequenceSet#[]`=20subset=20slicing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Except for the call-seq, the `SequenceSet#[]` only really documented using it as an alternate form for `SequenceSet#at`. --- lib/net/imap/sequence_set.rb | 119 +++++++++++++++++++++++++++++++---- 1 file changed, 107 insertions(+), 12 deletions(-) diff --git a/lib/net/imap/sequence_set.rb b/lib/net/imap/sequence_set.rb index 82c5e4a18..827d331fe 100644 --- a/lib/net/imap/sequence_set.rb +++ b/lib/net/imap/sequence_set.rb @@ -1739,16 +1739,49 @@ def ordered_at(index) # :call-seq: # seqset[index] -> integer or :* or nil # slice(index) -> integer or :* or nil - # seqset[start, length] -> sequence set or nil - # slice(start, length) -> sequence set or nil + # seqset[index, length] -> sequence set or nil + # slice(index, length) -> sequence set or nil # seqset[range] -> sequence set or nil # slice(range) -> sequence set or nil # # Returns a number or a subset from the _sorted_ set, without modifying # the set. # + # With a single +index+ argument, returns an integer or +:*+ or nil: + # set = Net::IMAP::SequenceSet["10:15,20:23,26"] + # set[0] #=> 10 + # set[-1] #=> 26 + # + # With +index+ and +length+ arguments, returns a new SequenceSet or nil: + # set = Net::IMAP::SequenceSet["10:15,20:23,26"] + # set[1, 2] #=> Net::IMAP::SequenceSet["11:12"] + # set[-2, 2] #=> Net::IMAP::SequenceSet["23,26"] + # + # With a single +range+ argument, returns a new SequenceSet or nil: + # set = Net::IMAP::SequenceSet["10:15,20:23,26"] + # set[0...2] #=> Net::IMAP::SequenceSet["10:11"] + # set[0..2] #=> Net::IMAP::SequenceSet["11:12"] + # set[0..-2] #=> Net::IMAP::SequenceSet["10:15,20:23"] + # set[-6..6] #=> Net::IMAP::SequenceSet["15,20"] + # + # Note that the result is based on the sorted and de-duplicated set, not + # on the ordered #entries in #string. + # + # set = Net::IMAP::SequenceSet["12,20:23,11:16,21"] + # set[0] #=> 11 + # set[-1] #=> 23 + # + # This behaves like Array#slice on a virtual array of all of the + # monotonically sorted #numbers in +self+: + # # WARNING: For illustration only. Do NOT do this with large sets. + # sliced_array = seqset.numbers[*args] and + # sliced_set = Net::IMAP::SequenceSet(sliced_array) + # set.slice(*args) == sliced_set #=> true + # + # ==== Number lookup by index + # # When an Integer argument +index+ is given, the number at offset +index+ - # in the sorted set is returned: + # in the sorted set is returned. # # set = Net::IMAP::SequenceSet["10:15,20:23,26"] # set[0] #=> 10 @@ -1759,22 +1792,84 @@ def ordered_at(index) # set = Net::IMAP::SequenceSet["10:15,20:23,26"] # set[-1] #=> 26 # set[-3] #=> 22 - # set[-6] #=> 15 - # - # If +index+ is out of range, +nil+ is returned. + # set[-11] #=> 10 # + # The range for +index+ is -cardinality...cardinality. + # If +index+ is out of range, returns +nil+. # set = Net::IMAP::SequenceSet["10:15,20:23,26"] # set[11] #=> nil # set[-12] #=> nil # - # The result is based on the sorted and de-duplicated set, not on the - # ordered #entries in #string. + # With a single Integer argument, this behaves identically to #at. # - # set = Net::IMAP::SequenceSet["12,20:23,11:16,21"] - # set[0] #=> 11 - # set[-1] #=> 23 + # ==== Subset slice by index and length + # + # When two Integer arguments, +index+ and +length+ are given, returns a + # new SequenceSet containing the +length+ successive numbers beginning at + # offset +index+.: + # set = Net::IMAP::SequenceSet["10:15,20:23,26"] + # set[0, 2] #=> Net::IMAP::SequenceSet["10:11"] + # set[1, 2] #=> Net::IMAP::SequenceSet["11:12"] + # + # If index + length is greater than #cardinality, returns all + # elements from +index+ to the end: + # set = Net::IMAP::SequenceSet["10:15,20:23,26"] + # set[0, 15] #=> Net::IMAP::SequenceSet["10:15,20:23,26"] + # set[5, 10] #=> Net::IMAP::SequenceSet["15,20:23,26"] + # set[10, 5] #=> Net::IMAP::SequenceSet["26"] + # + # If +index+ is equal to #cardinality, returns a new empty SequenceSet. + # set = Net::IMAP::SequenceSet["10:15,20:23,26"] + # set[11, 5] #=> Net::IMAP::SequenceSet.empty + # + # If +length+ is negative, returns +nil+. + # set = Net::IMAP::SequenceSet[1..10] + # set[5, -1] #=> nil + # + # If +index+ is out of range (absolute value greater than #cardinality), + # returns +nil+. + # + # If +index+ is in range and +length+ is zero, returns a new empty + # SequenceSet. + # + # ==== Subset slice by index range + # + # When a single Range argument +range+ is given, returns a new SequenceSet + # containing the successive numbers at the offsets indicated by +range+. + # + # set = Net::IMAP::SequenceSet["10:15,20:23,26"] + # set[0...2] #=> Net::IMAP::SequenceSet["10:11"] + # set[2..4] #=> Net::IMAP::SequenceSet["12:14"] + # + # set[-2..-1] #=> Net::IMAP::SequenceSet["23,26"] + # set[-4...-2] #=> Net::IMAP::SequenceSet["21:22"] + # + # set[4..-4] #=> Net::IMAP::SequenceSet["14:15,20:21"] + # set[-6...6] #=> Net::IMAP::SequenceSet["15"] + # + # An end-less range slices until the last number, and a begin-less range + # slices from the first number. + # set = Net::IMAP::SequenceSet["10:15,20:23,26"] + # set[..3] #=> Net::IMAP::SequenceSet["10:13"] + # set[..-3] #=> Net::IMAP::SequenceSet["10:15,20:22"] + # set[-2..] #=> Net::IMAP::SequenceSet["23,26"] + # set[2..] #=> Net::IMAP::SequenceSet["12:15,20:23,26"] + # + # When +range.begin+ points to a smaller index than +range.end+, a new + # empty SequenceSet is returned. + # + # set = Net::IMAP::SequenceSet[1..10] + # set[5.. 4] #=> SequenceSet.empty + # set[-4..-5] #=> SequenceSet.empty + # set[5..-6] #=> SequenceSet.empty + # + # If +range.begin+ is out of range (absolute value greater than + # #cardinality), returns +nil+. # - # Related: #at + # This behaves similarly to a slice with +range.begin+ as +index+ and + # +range.size+ as +length+, when that both sides of the range are either + # negative or non-negative. Note that the minimum +range.size+ is zero, + # so this can't return +nil+ for a negative range length. def [](index, length = nil) if length then slice_length(index, length) elsif index.is_a?(Range) then slice_range(index)