From fbbed337af4dbd8cd54190e1b1f042ca8bef174d Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Tue, 4 Nov 2025 17:05:18 +0000 Subject: [PATCH 1/3] [DOC] Tweaks for StringIO#each_line --- doc/stringio/each_line.md | 187 ++++++++++++++++++++++++++++++++++++++ ext/stringio/stringio.c | 164 +-------------------------------- 2 files changed, 188 insertions(+), 163 deletions(-) create mode 100644 doc/stringio/each_line.md diff --git a/doc/stringio/each_line.md b/doc/stringio/each_line.md new file mode 100644 index 0000000..698897a --- /dev/null +++ b/doc/stringio/each_line.md @@ -0,0 +1,187 @@ +With a block given calls the block with each remaining line (see "Position" below) in the stream; +returns `self`. + +Leaves stream position at end-of-stream. + +**No Arguments** + +With no arguments given, +reads lines using the default record separator +(global variable `$/`, whose initial value is `"\n"`). + +``` +strio = StringIO.new(TEXT) +strio.each_line {|line| p line } +strio.eof? # => true +``` + +Output: + +``` +"First line\n" +"Second line\n" +"\n" +"Fourth line\n" +"Fifth line\n" +``` + +**Argument `sep`** + +With only string argument `sep` given, +reads lines using that string as the record separator: + +``` +strio = StringIO.new(TEXT) +strio.each_line(' ') {|line| p line } +``` + +Output: + +``` +"First " +"line\nSecond " +"line\n\nFourth " +"line\nFifth " +"line\n" +``` + +**Argument `limit`** + +With only integer argument `limit` given, +reads lines using the default record separator; +also limits the size (in characters) of each line to the given limit: + +``` +strio = StringIO.new(TEXT) +strio.each_line(10) {|line| p line } +``` + +Output: + +``` +"First line" +"\n" +"Second lin" +"e\n" +"\n" +"Fourth lin" +"e\n" +"Fifth line" +"\n" +``` +**Arguments `sep` and `limit`** + +With arguments `sep` and `limit` both given, +honors both: + +``` +strio = StringIO.new(TEXT) +strio.each_line(' ', 10) {|line| p line } +``` + +Output: + +``` +"First " +"line\nSecon" +"d " +"line\n\nFour" +"th " +"line\nFifth" +" " +"line\n" +``` + +**Position** + +As stated above, method `each` _remaining_ line in the stream. + +In the examples above each `strio` object starts with its position at beginning-of-stream; +but in other cases the position may be anywhere (see StringIO#pos): + +``` +strio = StringIO.new(TEXT) +strio.pos = 30 # Set stream position to character 30. +strio.each_line {|line| p line } +``` + +Output: + +``` +" line\n" +"Fifth line\n" +``` + +In all the examples above, the stream position is at the beginning of a character; +in other cases, that need not be so: + +```ruby +s = 'こんにちは' # Five 3-byte characters. +strio = StringIO.new(s) +strio.pos = 3 # At beginning of second character. +strio.each_line {|line| p line } +strio.pos = 4 # At second byte of second character. +strio.each_line {|line| p line } +strio.pos = 5 # At third byte of second character. +strio.each_line {|line| p line } +``` + +Output: + +```ruby +"んにちは" +"\x82\x93にちは" +"\x93にちは" +``` + +**Special Record Separators** + +Like some methods in class `IO`, StringIO.each honors two special record separators; +see {Special Line Separators}[https://docs.ruby-lang.org/en/master/IO.html#class-IO-label-Special+Line+Separator+Values]. + +``` +strio = StringIO.new(TEXT) +strio.each_line('') {|line| p line } # Read as paragraphs (separated by blank lines). +``` + +Output: + +``` +"First line\nSecond line\n\n" +"Fourth line\nFifth line\n" +``` + +``` +strio = StringIO.new(TEXT) +strio.each_line(nil) {|line| p line } # "Slurp"; read it all. +``` + +Output: + +``` +"First line\nSecond line\n\nFourth line\nFifth line\n" +``` + +**Keyword Argument `chomp`** + +With keyword argument `chomp` given as `true` (the default is `false`), +removes trailing newline (if any) from each line: + +``` +strio = StringIO.new(TEXT) +strio.each_line(chomp: true) {|line| p line } +``` + +Output: + +``` +"First line" +"Second line" +"" +"Fourth line" +"Fifth line" +``` + +With no block given, returns a new {Enumerator}[https://docs.ruby-lang.org/en/master/Enumerator.html]. + +Related: StringIO.each_byte, StringIO.each_char, StringIO.each_codepoint. diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 874a3a1..05772aa 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -1466,170 +1466,8 @@ strio_readline(int argc, VALUE *argv, VALUE self) * each_line(limit, chomp: false) {|line| ... } -> self * each_line(sep, limit, chomp: false) {|line| ... } -> self * - * With a block given calls the block with each remaining line (see "Position" below) in the stream; - * returns `self`. + * :include: stringio/each_line.md * - * Leaves stream position as end-of-stream. - * - * **No Arguments** - * - * With no arguments given, - * reads lines using the default record separator global variable `$/`, whose initial value is `"\n"`. - * - * ``` - * strio = StringIO.new(TEXT) - * strio.each_line {|line| p line } - * strio.eof? # => true - * ``` - * - * Output: - * - * ``` - * "First line\n" - * "Second line\n" - * "\n" - * "Fourth line\n" - * "Fifth line\n" - * ``` - * - * **Argument `sep`** - * - * With only string argument `sep` given, - * reads lines using that string as the record separator: - * - * ``` - * strio = StringIO.new(TEXT) - * strio.each_line(' ') {|line| p line } - * ``` - * - * Output: - * - * ``` - * "First " - * "line\nSecond " - * "line\n\nFourth " - * "line\nFifth " - * "line\n" - * ``` - * - * **Argument `limit`** - * - * With only integer argument `limit` given, - * reads lines using the default record separator global variable `$/`, whose initial value is `"\n"`; - * also limits the size (in characters) of each line to the given limit: - * - * ``` - * strio = StringIO.new(TEXT) - * strio.each_line(10) {|line| p line } - * ``` - * - * Output: - * - * ``` - * "First line" - * "\n" - * "Second lin" - * "e\n" - * "\n" - * "Fourth lin" - * "e\n" - * "Fifth line" - * "\n" - * ``` - * **Arguments `sep` and `limit`** - * - * With arguments `sep` and `limit` both given, - * honors both: - * - * ``` - * strio = StringIO.new(TEXT) - * strio.each_line(' ', 10) {|line| p line } - * ``` - * - * Output: - * - * ``` - * "First " - * "line\nSecon" - * "d " - * "line\n\nFour" - * "th " - * "line\nFifth" - * " " - * "line\n" - * ``` - * - * **Position** - * - * As stated above, method `each` _remaining_ line in the stream. - * - * In the examples above each `strio` object starts with its position at beginning-of-stream; - * but in other cases the position may be anywhere (see StringIO#pos): - * - * ``` - * strio = StringIO.new(TEXT) - * strio.pos = 30 # Set stream position to character 30. - * strio.each_line {|line| p line } - * ``` - * - * Output: - * - * ``` - * " line\n" - * "Fifth line\n" - * ``` - * - * **Special Record Separators** - * - * Like some methds in class `IO`, StringIO.each honors two special record separators; - * see {Special Line Separators}[https://docs.ruby-lang.org/en/master/IO.html#class-IO-label-Special+Line+Separator+Values]. - * - * ``` - * strio = StringIO.new(TEXT) - * strio.each_line('') {|line| p line } # Read as paragraphs (separated by blank lines). - * ``` - * - * Output: - * - * ``` - * "First line\nSecond line\n\n" - * "Fourth line\nFifth line\n" - * ``` - * - * ``` - * strio = StringIO.new(TEXT) - * strio.each_line(nil) {|line| p line } # "Slurp"; read it all. - * ``` - * - * Output: - * - * ``` - * "First line\nSecond line\n\nFourth line\nFifth line\n" - * ``` - * - * **Keyword Argument `chomp`** - * - * With keyword argument `chomp` given as `true` (the default is `false`), - * removes trailing newline (if any) from each line: - * - * ``` - * strio = StringIO.new(TEXT) - * strio.each_line(chomp: true) {|line| p line } - * ``` - * - * Output: - * - * ``` - * "First line" - * "Second line" - * "" - * "Fourth line" - * "Fifth line" - * ``` - * - * With no block given, returns a new {Enumerator}[https://docs.ruby-lang.org/en/master/Enumerator.html]. - * - * Related: StringIO.each_byte, StringIO.each_char, StringIO.each_codepoint. */ static VALUE strio_each(int argc, VALUE *argv, VALUE self) From fca8dc95d75db74e99088c0b9f59dbd66c0277c1 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Tue, 4 Nov 2025 19:45:42 -0600 Subject: [PATCH 2/3] Update doc/stringio/each_line.md Co-authored-by: Sutou Kouhei --- doc/stringio/each_line.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/stringio/each_line.md b/doc/stringio/each_line.md index 698897a..eb2dd04 100644 --- a/doc/stringio/each_line.md +++ b/doc/stringio/each_line.md @@ -128,7 +128,6 @@ strio.each_line {|line| p line } Output: -```ruby "んにちは" "\x82\x93にちは" "\x93にちは" From 45eaeb11572b7a176cd10444adaacd7f394a9d10 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Tue, 4 Nov 2025 19:46:04 -0600 Subject: [PATCH 3/3] Update doc/stringio/each_line.md Co-authored-by: Sutou Kouhei --- doc/stringio/each_line.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/stringio/each_line.md b/doc/stringio/each_line.md index eb2dd04..d75d315 100644 --- a/doc/stringio/each_line.md +++ b/doc/stringio/each_line.md @@ -9,7 +9,7 @@ With no arguments given, reads lines using the default record separator (global variable `$/`, whose initial value is `"\n"`). -``` +```ruby strio = StringIO.new(TEXT) strio.each_line {|line| p line } strio.eof? # => true