Skip to content

Commit

Permalink
add missing documentation to String methods crystal-lang#2
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-zajic committed Jan 2, 2020
1 parent 96182cb commit c3473c4
Showing 1 changed file with 71 additions and 49 deletions.
120 changes: 71 additions & 49 deletions src/string.cr
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ class String
#
# Negative indices can be used to start counting from the end of the string.
#
# Raises `IndexError` if the *index* is out of range.
# Raises `IndexError` if the *index* is out of bounds.
#
# ```
# "hello"[0] # => 'h'
Expand All @@ -741,7 +741,7 @@ class String
# as character indices. Indices can be negative to start
# counting from the end of the string.
#
# Raises `IndexError` if the range's start is out of range.
# Raises `IndexError` if the range's start is out of bounds.
#
# ```
# "hello"[0..2] # => "hel"
Expand All @@ -754,7 +754,7 @@ class String
self[*Indexable.range_to_index_and_count(range, size)]
end

# Like `#[Range(Int, Int)]`, but returns `nil` if the range's start is out of range.
# Like `#[Range(Int, Int)]`, but returns `nil` if the range's start is out of bounds.
#
# ```
# "hello"[6..7]? # => nil
Expand All @@ -765,17 +765,17 @@ class String

# Returns a substring starting from the *start* character of size *count*.
#
# The *start* argument can be negative to start counting
# *start* can can be negative to start counting
# from the end of the string.
#
# Raises `IndexError` if the *start* index is out of range.
# Raises `IndexError` if the *start* index is out of bounds.
#
# Raises `ArgumentError` if *count* is negative.
def [](start : Int, count : Int)
self[start, count]? || raise IndexError.new
end

# Like `#[Int, Int]` but returns `nil` if the *start* index is out of range.
# Like `#[Int, Int]` but returns `nil` if the *start* index is out of bounds.
def []?(start : Int, count : Int)
raise ArgumentError.new "Negative count: #{count}" if count < 0
return byte_slice?(start, count) if ascii_only?
Expand Down Expand Up @@ -859,7 +859,7 @@ class String
#
# Negative indices can be used to start counting from the end of the string.
#
# Raises `IndexError` if the *index* is out of range.
# Raises `IndexError` if the *index* is out of bounds.
#
# ```
# "hello".char_at(0) # => 'h'
Expand All @@ -877,8 +877,11 @@ class String
# Negative indices can be used to start counting from the end of the string.
#
# ```
# "hello".char_at(4) { 'x' } # => 'o'
# "hello".char_at(5) { 'x' } # => 'x'
# "hello".char_at(4) { 'x' } # => 'o'
# "hello".char_at(5) { 'x' } # => 'x'
# "hello".char_at(-1) { 'x' } # => 'o'
# "hello".char_at(-5) { 'x' } # => 'h'
# "hello".char_at(-6) { 'x' } # => 'x'
# ```
def char_at(index : Int, &)
if ascii_only?
Expand All @@ -901,18 +904,18 @@ class String
end
end

# Returns a new string consisted of *count* bytes starting at *start* byte.
# Returns a new string built from *count* bytes starting at *start* byte.
#
# The *start* argument can be negative to start counting
# *start* can can be negative to start counting
# from the end of the string.
# If `count` is bigger than number of bytes from *start* to `bytelen`,
# If *count* is bigger than the number of bytes from *start* to `#bytesize`,
# only remaining bytes are returned.
#
# Be careful when working with multibyte characters - they can be splitted,
# which may lead to invalid UTF-8 values. These,
# when asked as chars, will use the unicode replacement �.
#
# Raises `IndexError` if the *start* index is out of range.
# Raises `IndexError` if the *start* index is out of bounds.
#
# Raises `ArgumentError` if *count* is negative.
#
Expand All @@ -935,7 +938,17 @@ class String
byte_slice?(start, count) || raise IndexError.new
end

# Like `byte_slice(Int, Int)` but returns `Nil` if the *start* index is out of range.
# Like `byte_slice(Int, Int)` but returns `Nil` if the *start* index is out of bounds.
#
# Raises `ArgumentError` if *count* is negative.
#
# ```
# "hello".byte_slice(0, 2) # => "he"
# "hello".byte_slice(0, 100) # => "hello"
# "hello".byte_slice(6, 2) # => nil
# "hello".byte_slice(-6, 2) # => nil
# "hello".byte_slice(0, -2) # raises ArgumentError
# ```
def byte_slice?(start : Int, count : Int) : String | Nil
raise ArgumentError.new "Negative count" if count < 0

Expand All @@ -957,21 +970,15 @@ class String
end
end

def byte_slice(start : Int) : String
count = bytesize - start
raise IndexError.new if start > 0 && count < 0
byte_slice start, count
end

# Returns a substring starting from the *start* byte.
#
# The *start* argument can be negative to start counting
# *start* can can be negative to start counting
# from the end of the string.
#
# Be careful when working with multibyte characters - they can be splitted
# which may lead to unexpected result.
#
# Raises `IndexError` if *start* index is out of range.
# Raises `IndexError` if *start* index is out of bounds.
#
# ```
# "hello".byte_slice(0) # => "hello"
Expand All @@ -982,9 +989,17 @@ class String
# "hello".byte_slice(6) # raises IndexError
# "hello".byte_slice(-6) # raises IndexError
# ```
# Returns the codepoint of `Char` at the given *index*.
def byte_slice(start : Int) : String
count = bytesize - start
raise IndexError.new if start > 0 && count < 0
byte_slice start, count
end

# Returns the codepoint of the character at the given *index*.
#
# Raises `IndexError` if the *index* is out of range.
# Negative indices can be used to start counting from the end of the string.
#
# Raises `IndexError` if the *index* is out of bounds.
#
# See also: `Char#ord`.
#
Expand All @@ -1000,7 +1015,7 @@ class String

# Returns the byte at the given *index*.
#
# Raises `IndexError` if the *index* is out of range.
# Raises `IndexError` if the *index* is out of bounds.
#
# ```
# "¥hello".byte_at(0) # => 194
Expand All @@ -1014,7 +1029,7 @@ class String
byte_at(index) { raise IndexError.new }
end

# Returns the byte at the given *index*, or nil if out of bounds.
# Returns the byte at the given *index*, or `nil` if out of bounds.
#
# ```
# "¥hello".byte_at(0) # => 194
Expand All @@ -1028,11 +1043,11 @@ class String
byte_at(index) { nil }
end

# Returns the byte at the given *index*, or yield if out of bounds.
# Returns the byte at the given *index*, or yields if out of bounds.
#
# ```
# "¥hello".byte_at(6) { 0 } # => 111
# "¥hello".byte_at(7) { 0 } # => 0
# "¥hello".byte_at(6) { "OUT OF BOUNDS" } # => 111
# "¥hello".byte_at(7) { "OUT OF BOUNDS" } # => "OUT OF BOUNDS"
# ```
def byte_at(index, &)
index += bytesize if index < 0
Expand Down Expand Up @@ -2536,8 +2551,8 @@ class String
self if !blank?
end

# Returns `true` if this string is the same as other.
# Comparison is done byte-per-byte: if a byte is less then the other corresponding
# Returns `true` if this string is equal to `*other*.
# Comparison is done byte-per-byte: if a byte is different from the corresponding
# byte, `false` is returned and so on.
def ==(other : self) : Bool
return true if same?(other)
Expand Down Expand Up @@ -3065,7 +3080,7 @@ class String
# "Hello, World".byte_index(0x6f, 5) # => 8
# "💣".byte_index(0xA3) # => 3
# ```
def byte_index(byte : Int, offset = 0)
def byte_index(byte : Int, offset = 0) : Int32?
offset.upto(bytesize - 1) do |i|
if to_unsafe[i] == byte
return i
Expand All @@ -3077,10 +3092,17 @@ class String
# Returns the byte index of *search* in the string, or `nil` if the string is not present.
# If *offset* is present, it defines the position to start the search.
#
# # Negative *offset* can be used to start the search from the end of the string.
#
# ```
# "¥hello".byte_index("hello") # => 2
# "¥hello".byte_index("hello") # => 2
# "hello".byte_index("world") # => nil
# "Dizzy Miss Lizzy".byte_index("izzy") # => 1
# "Dizzy Miss Lizzy".byte_index("izzy", 2) # => 12
# "Dizzy Miss Lizzy".byte_index("izzy", -4) # => 12
# "Dizzy Miss Lizzy".byte_index("izzy", -4) # => nil
# ```
def byte_index(search : String, offset = 0)
def byte_index(search : String, offset = 0) : Int32?
offset += bytesize if offset < 0
return if offset < 0

Expand Down Expand Up @@ -4245,7 +4267,7 @@ class String
io << '}' if char.ord > 0xFFFF
end

# Returns true if this string starts with the given *str*, otherwise `false`.
# Returns `true` if this string starts with the given *str*.
#
# ```
# "hello".starts_with?("h") # => true
Expand All @@ -4257,7 +4279,7 @@ class String
to_unsafe.memcmp(str.to_unsafe, str.bytesize) == 0
end

# Returns `true` if this string starts with the given *char*, otherwise `false`.
# Returns `true` if this string starts with the given *char*.
#
# ```
# "hello".starts_with?('h') # => true
Expand All @@ -4271,7 +4293,7 @@ class String
false
end

# Returns true if this string starts with the given *re* regular expression, otherwise `false`.
# Returns `true` if the regular expression *re* matches at the start of this string.
#
# ```
# "22hello".starts_with?(/[0-9]/) # => true
Expand All @@ -4285,7 +4307,7 @@ class String
!!($~ = re.match_at_byte_index(self, 0, Regex::Options::ANCHORED))
end

# Returns true if this string ends with the given *str*, otherwise `false`.
# Returns `true` if this string ends with the given *str*.
#
# ```
# "hello".ends_with?("o") # => true
Expand All @@ -4297,7 +4319,7 @@ class String
(to_unsafe + bytesize - str.bytesize).memcmp(str.to_unsafe, str.bytesize) == 0
end

# Returns true if this string ends with the given *char*, otherwise `false`.
# Returns `true` if this string ends with the given *char*.
#
# ```
# "hello".ends_with?('o') # => true
Expand All @@ -4320,7 +4342,7 @@ class String
true
end

# Returns true if this string ends with the given *re* regular expression, otherwise `false`.
# Returns `true` if the regular expression *re* matches at the end of this string.
#
# ```
# "22hello".ends_with?(/[0-9]/) # => false
Expand Down Expand Up @@ -4469,27 +4491,27 @@ class String
char_index
end

# Returns `self`
# Returns `self`.
def clone : String
self
end

# Returns `self`
# ditto
def dup : String
self
end

# Returns `self`
# ditto
def to_s : String
self
end

# Appends `self` characters to the given IO object.
# Appends `self` to *io*.
def to_s(io : IO) : Nil
io.write_utf8(to_slice)
end

# Returns the underlying bytes of this String in an **unsafe** way.
# Returns the underlying bytes of this String.
#
# The returned slice is read-only.
def to_slice : Bytes
Expand All @@ -4501,17 +4523,17 @@ class String
pointerof(@c)
end

# Returns *count* of underlying bytes of this String starting at given *byte_offset* in an **unsafe** way.
# Returns *count* of underlying bytes of this String starting at given *byte_offset*.
#
# The returned slice is read-only.
def unsafe_byte_slice(byte_offset, count)
def unsafe_byte_slice(byte_offset, count) : Slice
Slice.new(to_unsafe + byte_offset, count, read_only: true)
end

# Returns the underlying bytes of this String starting at given *byte_offset* in an **unsafe** way.
# Returns the underlying bytes of this String starting at given *byte_offset*.
#
# The returned slice is read-only.
def unsafe_byte_slice(byte_offset)
def unsafe_byte_slice(byte_offset) : Slice
Slice.new(to_unsafe + byte_offset, bytesize - byte_offset, read_only: true)
end

Expand Down

0 comments on commit c3473c4

Please sign in to comment.