Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation of Array#[Range] #10243

Merged
66 changes: 48 additions & 18 deletions src/array.cr
Original file line number Diff line number Diff line change
Expand Up @@ -581,22 +581,54 @@ class Array(T)

# Returns all elements that are within the given range.
#
# Negative indices count backward from the end of the array (-1 is the last
# element). Additionally, an empty array is returned when the starting index
# for an element range is at the end of the array.
#
# Raises `IndexError` if the range's start is out of range.
# The first element in the returned array is `self[range.begin]` followed
# by the next elements up to index `range.end` (or `range.end - 1` if the range
# is exclusive).
# If there are fewer elements in `self`, the returned array is shorter than
# `range.size`.
#
# ```
# a = ["a", "b", "c", "d", "e"]
# a[1..3] # => ["b", "c", "d"]
# a[4..7] # => ["e"]
# # range.end > array.size
# a[3..7] # => ["d", "e"]
# ```
#
# Open ended ranges are clamped at the start and end of the array, respectively.
#
# ```
# # open ended ranges
# a[2..] # => ["c", "d", "e"]
# a[..2] # => ["a", "b", "c"]
# ```
#
# Negative range values are added to `self.size`, thus they are treated as
# indices counting from the end of the array, `-1` designating the last element.
#
# ```
# # negative indices, both ranges are equivalent for `a`
# a[1..3] # => ["b", "c", "d"]
# a[-4..-2] # => ["b", "c", "d"]
# # Mixing negative and positive indices, both ranges are equivalent for `a`
# a[1..-2] # => ["b", "c", "d"]
# a[-4..3] # => ["b", "c", "d"]
# ```
#
# Raises `IndexError` if the start index it out of range (`range.begin >
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
# self.size || range.begin < -self.size). If `range.begin == self.size` an
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
# empty array is returned. If `range.begin > range.end`, an empty array is
# returned.
#
# ```
# # range.begin > array.size
# a[6..10] # raise IndexError
# # range.begin == array.size
# a[5..10] # => []
# a[-2...-1] # => ["d"]
# a[2..] # => ["c", "d", "e"]
# # range.begin > range.end
# a[3..1] # => []
# a[-2..-4] # => []
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
# ```
def [](range : Range)
def [](range : Range) : self
self[*Indexable.range_to_index_and_count(range, size) || raise IndexError.new]
end

Expand All @@ -607,20 +639,18 @@ class Array(T)
# a[6..10]? # => nil
# a[6..]? # => nil
# ```
def []?(range : Range)
def []?(range : Range) : self | Nil
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
self[*Indexable.range_to_index_and_count(range, size) || return nil]?
end

# Returns count or less (if there aren't enough) elements starting at the
# given start index.
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
#
# Negative indices count backward from the end of the array (-1 is the last
# element). Additionally, an empty array is returned when the starting index
# for an element range is at the end of the array.
#
# Raises `IndexError` if the *start* index is out of range.
# Negative *start* is added to `self.size`, thus it's treated as
# index counting from the end of the array, `-1` designating the last element.
#
# Raises `ArgumentError` if *count* is negative.
# If `start >= self.size` or `start < -self.size`, an empty array is returned.
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
# Raises `ArgumentError` if *start* is negative.
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
#
# ```
# a = ["a", "b", "c", "d", "e"]
Expand All @@ -629,12 +659,12 @@ class Array(T)
# a[5, 1] # => []
# a[6, 1] # raises IndexError
# ```
def [](start : Int, count : Int)
def [](start : Int, count : Int) : self
self[start, count]? || raise IndexError.new
end

# Like `#[Int, Int]` but returns `nil` if the *start* index is out of range.
def []?(start : Int, count : Int)
def []?(start : Int, count : Int) : self | Nil
raise ArgumentError.new "Negative count: #{count}" if count < 0
return Array(T).new if start == size

Expand Down