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 Apr 8, 2020
1 parent 4bfd993 commit 352373b
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 @@ -729,7 +729,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 @@ -746,7 +746,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 @@ -759,7 +759,7 @@ class String
self[*Indexable.range_to_index_and_count(range, size)]
end

# Like `#[Range]`, but returns `nil` if the range's start is out of range.
# Like `#[Range]`, but returns `nil` if the range's start is out of bounds.
#
# ```
# "hello"[6..7]? # => nil
Expand All @@ -771,17 +771,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 @@ -855,7 +855,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 @@ -873,8 +873,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 @@ -897,18 +900,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 @@ -931,7 +934,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 @@ -953,21 +966,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 @@ -978,9 +985,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*.
#
# 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.
#
# See also: `Char#ord`.
#
Expand All @@ -995,7 +1010,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 @@ -1009,7 +1024,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 @@ -1023,11 +1038,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 @@ -2532,8 +2547,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 @@ -3061,7 +3076,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 @@ -3073,10 +3088,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 @@ -4351,7 +4373,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 @@ -4363,7 +4385,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 @@ -4377,7 +4399,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 @@ -4391,7 +4413,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 @@ -4403,7 +4425,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 @@ -4426,7 +4448,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 @@ -4575,27 +4597,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 @@ -4607,17 +4629,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 352373b

Please sign in to comment.