Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions spec/std/string_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2700,8 +2700,17 @@ describe "String" do
lines.should eq(["foo\n", "\n", "bar\r\n", "baz\r\n"])
end

it "gets each_line with remove_empty = true" do
lines = [] of String
"\nfoo\n\nbar\r\nbaz\n\n".each_line(remove_empty: true) do |line|
lines << line
end.should be_nil
lines.should eq(["foo", "bar", "baz"])
end

it_iterates "#each_line", ["foo", "bar", "baz"], "foo\nbar\r\nbaz\r\n".each_line
it_iterates "#each_line(chomp: false)", ["foo\n", "bar\r\n", "baz\r\n"], "foo\nbar\r\nbaz\r\n".each_line(chomp: false)
it_iterates "#each_line(remove_empty: true)", ["foo", "bar", "baz"], "\nfoo\n\nbar\r\nbaz\n\n".each_line(remove_empty: true)

it_iterates "#each_codepoint", [97, 98, 9731], "ab☃".each_codepoint

Expand Down
16 changes: 11 additions & 5 deletions src/string.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4395,6 +4395,8 @@ class String
# "hello\nworld\r\n".each_line(chomp: false) { } # yields "hello\n", "world\r\n"
# ```
#
# If *remove_empty* is `true`, any empty strings are removed from the result.
#
# A trailing line feed is not considered starting a final, empty line. The
# empty string does not contain any lines.
#
Expand All @@ -4405,7 +4407,7 @@ class String
# ```
#
# * `#lines` returns an array of lines
def each_line(chomp : Bool = true, & : String ->) : Nil
def each_line(chomp : Bool = true, remove_empty : Bool = false, & : String ->) : Nil
return if empty?

offset = 0
Expand All @@ -4419,7 +4421,7 @@ class String
end
end

yield unsafe_byte_slice_string(offset, count)
yield unsafe_byte_slice_string(offset, count) unless remove_empty && count == 0
offset = byte_index + 1
end

Expand All @@ -4429,8 +4431,8 @@ class String
end

# Returns an `Iterator` which yields each line of this string (see `String#each_line`).
def each_line(chomp = true)
LineIterator.new(self, chomp)
def each_line(chomp = true, remove_empty = false)
LineIterator.new(self, chomp, remove_empty)
end

# Converts camelcase boundaries to underscores.
Expand Down Expand Up @@ -5699,7 +5701,7 @@ class String
private class LineIterator
include Iterator(String)

def initialize(@string : String, @chomp : Bool)
def initialize(@string : String, @chomp : Bool, @remove_empty : Bool)
@offset = 0
@end = false
end
Expand Down Expand Up @@ -5728,6 +5730,10 @@ class String
@end = true
end

if @remove_empty && !@end && value.is_a?(String) && value.as(String).bytesize == 0
value = self.next
end

value
end
end
Expand Down
Loading