From 3f17d17807d1ebf565544898a027f533ed0ae4e0 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 5 Nov 2025 18:09:27 +0000 Subject: [PATCH 01/34] [DOC] Doc for class StringIO --- doc/stringio/stringio.md | 105 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 4 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 345fc5f2..b8bcdea7 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -1,8 +1,29 @@ -\IO streams for strings, with access similar to -{IO}[rdoc-ref:IO]; -see {IO}[rdoc-ref:IO]. +\Class \StringIO supports accessing a string as a stream, +similar in some ways to [class IO][class io]. -### About the Examples +You can create a \StingIO instance using: + +- StringIO.new(string): returns a new \StringIO object containing the given string. +- StringIO.open(string): passes a new \StringIO object to the given block. + +Like an \IO stream, a \StringIO stream has certain properties: + +- **Read/write mode**: whether the stream may be read, written, appended to, etc.; + see [Read/Write Mode][read/write mode]. +- **Data mode**: text-only or binary; + see [Data Mode][data mode]. +- **Encodings**: internal and external encodings; + see [Encodings][encodings]. +- **Position**: where in the stream the next read or write is to occur; + see [Position][position]. +- **Line number**: a special, line-oriented, "position" (different from the position mentioned above); + see [Line Number][line number]. +- **Open/closed**: whether the stream is open or closed, for reading or writing. + see [Open/Closed Streams][open/closed streams]. +- **End-of-stream**: whether the position is at the end of the stream; + see [End-of-Stream][end-of-stream]. + +## About the Examples Examples on this page assume that \StringIO has been required: @@ -24,3 +45,79 @@ EOT RUSSIAN = 'тест' DATA = "\u9990\u9991\u9992\u9993\u9994" ``` + +## Stream Properties + +### Read/Write Mode + +### Data Mode + +### Encodings + +### Position + +### Line Number + +### Open/Closed Streams + +### End-of-Stream + +## Basic Stream \IO + +### Reading + +You can read immediately from the stream using these instance methods: + +- #getbyte: reads and returns the next byte. +- #getc: reads and returns the next character. +- #gets: reads and returns the next line. +- #read: reads and returns the remaining data in the stream. +- #readlines: reads the remaining data the stream and returns an array of its lines. + +You can iterate over the stream using these instance methods: + +- #each_byte: reads each remaining byte, passing it to the block. +- #each_char: reads each remaining character, passing it to the block. +- #each_codepoint: reads each remaining codepoint, passing it to the block. +- #each_line: reads each remaining line, passing it to the block + +This instance method is useful in a multi-threaded application: + +- #pread. + +### Writing + +You can write to the stream, advancing the position, using these instance methods: + +- #putc: write the given character. +- #write: write the given strings. + +You can "unshift" to the stream using these instance methods; +each writes at the current position, without advancing the position, +so that the written data is next to be read. + +- #ungetbyte: unshift the given byte. +- #ungetc.: unshift the given character. + +This instance method truncates the stream to the given size: + +- #truncate. + +## Line \IO + +## Character \IO + +## Byte \IO + +## Codepoint \IO + + +[class io]: https://docs.ruby-lang.org/en/master/IO.html + +[data mode]: rdoc-ref:StringIO@Data+Mode +[encodings]: rdoc-ref:StringIO@Encodings +[end-of-stream]: rdoc-ref:StringIO@End-of-Stream +[line number]: rdoc-ref:StringIO@Line+Number +[open/closed streams]: rdoc-ref:StringIO@Open-2FClosed+Streams +[position]: rdoc-ref:StringIO@Position +[read/write mode]: rdoc-ref:StringIO@Read-2FWrite+Mode From ccfca0b8b32e22d35e311be2033a2a72c4989e81 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 5 Nov 2025 19:26:54 +0000 Subject: [PATCH 02/34] More on read/write modes --- doc/stringio/stringio.md | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index b8bcdea7..ac10462d 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -50,6 +50,78 @@ DATA = "\u9990\u9991\u9992\u9993\u9994" ### Read/Write Mode +#### Read/Write Modes + +##### `'r'`: Read-Only. + +Initial state: + +```ruby +strio = StringIO.new(TEXT, 'r') +strio.pos # => 0 # Beginning of stream. +strio.string.size == 0 # => false # Not truncated. +``` + +May be written anywhere; see #rewind, #pos=, #seek: + +```ruby +strio.gets # => "First line\n" +strio.gets # => "Second line\n" + +strio.rewind +strio.gets # => "First line\n" + +strio.pos = 1 +strio.gets # => "irst line\n" + +strio.seek(1, IO::SEEK_CUR) +strio.gets # => "econd line\n" +``` + +May not be written: + +```ruby +strio.write('foo') # Raises IOError: not opened for writing +``` + +##### `'w'`: Write-Only. + +Initial state: + +```ruby +strio = StringIO.new(TEXT, 'w') +strio.pos # => 0 # Beginning of stream. +strio.string # => "" # Initially truncated. +``` +May be written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: + +```ruby +strio = StringIO.new(TEXT, 'w') +strio.write('foobar') +strio.string # => "foobar" + +strio.rewind +strio.write('FOO') +strio.string # => "FOObar" + +strio.pos = 3 +strio.write('BAR') +strio.string # => "FOOBAR" + +strio.seek(1, IO::SEEK_CUR) +strio.write('baz') +strio.string # => "FOOBAR\u0000baz" # Null-padded. + +strio.pos = 20 +strio.write('bat') +strio.string # => "FOOBAR\u0000baz\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000bat" +``` + +May not be read: + +```ruby +strio.read # Raises IOError: not opened for reading +``` ### Data Mode ### Encodings From be66cb6a418ec9d0ceb279239ccfdc9fc684ec06 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 5 Nov 2025 19:42:03 +0000 Subject: [PATCH 03/34] More on read/write modes --- doc/stringio/stringio.md | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index ac10462d..cb5a4e14 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -50,9 +50,7 @@ DATA = "\u9990\u9991\u9992\u9993\u9994" ### Read/Write Mode -#### Read/Write Modes - -##### `'r'`: Read-Only. +#### `'r'`: Read-Only. Initial state: @@ -84,7 +82,7 @@ May not be written: strio.write('foo') # Raises IOError: not opened for writing ``` -##### `'w'`: Write-Only. +#### `'w'`: Write-Only. Initial state: @@ -122,6 +120,38 @@ May not be read: ```ruby strio.read # Raises IOError: not opened for reading ``` + +#### `'a'`: Append-Only + +Initial state: + +```ruby +strio = StringIO.new('foo', 'a') +strio.pos # => 0 # Beginning-of-stream. +strio.string # => "foo" # Not truncated. +``` + +May be written only at the end; #rewind, #pos=, #seek do not affect writing: + +```ruby +strio.write('bar') +strio.string # => "foobar" +strio.write('baz') +strio.string # => "foobarbaz" + +strio.rewind +strio.pos = 400 +strio.seek(1, IO::SEEK_CUR) +strio.write('bat') +strio.string # => "foobarbazbat" +``` + +May not be read: + +```ruby +strio.gets # Raises IOError: not opened for reading +``` + ### Data Mode ### Encodings From 1cef4f47fe06e027ce78e6b2a2450bcd9bfa0dcd Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 5 Nov 2025 19:51:04 +0000 Subject: [PATCH 04/34] More on read/write modes --- doc/stringio/stringio.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index cb5a4e14..55bee87c 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -50,6 +50,17 @@ DATA = "\u9990\u9991\u9992\u9993\u9994" ### Read/Write Mode +Summary: + +| Mode | Truncate? | Read | Read Pos | Write | Write Pos | +|:----:|:---------:|:--------:|:--------:|:--------:|:---------:| +| 'r' | No | Anywhere | 0 | Error | - | +| 'w' | Yes | Error | - | Anywhere | 0 | +| 'a' | No | Error | - | End only | End | +| 'r+' | No | Anywhere | 0 | Anywhere | 0 | +| 'w+' | Yes | Anywhere | 0 | Anywhere | 0 | +| 'a+' | No | Anywhere | End | End only | End | + #### `'r'`: Read-Only. Initial state: @@ -152,6 +163,15 @@ May not be read: strio.gets # Raises IOError: not opened for reading ``` +#### `'r+'`: + + +#### `'w+'`: + + +#### `'a+'`: + + ### Data Mode ### Encodings From 6e0096c8ed82b0bd05d54b110fb4d5cb502e4c1e Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 5 Nov 2025 19:58:40 +0000 Subject: [PATCH 05/34] More on read/write modes --- doc/stringio/stringio.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 55bee87c..55b41f24 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -50,7 +50,7 @@ DATA = "\u9990\u9991\u9992\u9993\u9994" ### Read/Write Mode -Summary: +#### Summary | Mode | Truncate? | Read | Read Pos | Write | Write Pos | |:----:|:---------:|:--------:|:--------:|:--------:|:---------:| @@ -61,7 +61,7 @@ Summary: | 'w+' | Yes | Anywhere | 0 | Anywhere | 0 | | 'a+' | No | Anywhere | End | End only | End | -#### `'r'`: Read-Only. +#### `'r'`: Read-Only Initial state: @@ -93,7 +93,7 @@ May not be written: strio.write('foo') # Raises IOError: not opened for writing ``` -#### `'w'`: Write-Only. +#### `'w'`: Write-Only (Initial Truncate) Initial state: @@ -163,13 +163,13 @@ May not be read: strio.gets # Raises IOError: not opened for reading ``` -#### `'r+'`: +#### `'r+'`: Read/Write -#### `'w+'`: +#### `'w+'`: Read/Write (Initial Truncate) -#### `'a+'`: +#### `'a+'`: Read/Append ### Data Mode From df1d446cfefd98a528968cdbb617bca61f0bddfe Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 5 Nov 2025 21:02:26 +0000 Subject: [PATCH 06/34] More on read/write modes --- doc/stringio/stringio.md | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 55b41f24..eb8c59e1 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -52,14 +52,14 @@ DATA = "\u9990\u9991\u9992\u9993\u9994" #### Summary -| Mode | Truncate? | Read | Read Pos | Write | Write Pos | -|:----:|:---------:|:--------:|:--------:|:--------:|:---------:| -| 'r' | No | Anywhere | 0 | Error | - | -| 'w' | Yes | Error | - | Anywhere | 0 | -| 'a' | No | Error | - | End only | End | -| 'r+' | No | Anywhere | 0 | Anywhere | 0 | -| 'w+' | Yes | Anywhere | 0 | Anywhere | 0 | -| 'a+' | No | Anywhere | End | End only | End | +| Mode | Truncate? | Read | Read Pos | Write | Write Pos | +|:--------------------------:|:---------:|:--------:|:--------:|:--------:|:---------:| +| 'r': read-only | No | Anywhere | 0 | Error | - | +| 'w': write-only | Yes | Error | - | Anywhere | 0 | +| 'a': append-only | No | Error | - | End only | End | +| 'r+': read/write | No | Anywhere | 0 | Anywhere | 0 | +| 'w+': read-write | Yes | Anywhere | 0 | Anywhere | 0 | +| 'a+': read/append | No | Anywhere | End | End only | End | #### `'r'`: Read-Only @@ -165,6 +165,20 @@ strio.gets # Raises IOError: not opened for reading #### `'r+'`: Read/Write +Initial state: + +```ruby +strio = StringIO.new('foo', 'r+') +strio.pos # => 0 # Beginning-of-stream. +strio.string # => "foo" # Not truncated. +``` + +May be read or written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: + +```ruby + +``` + #### `'w+'`: Read/Write (Initial Truncate) From 9a626dd43fc1806ecb77aa3406fc310481ad27e5 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 5 Nov 2025 22:15:46 +0000 Subject: [PATCH 07/34] More on read/write modes --- doc/stringio/stringio.md | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index eb8c59e1..e6bdb5a6 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -98,14 +98,14 @@ strio.write('foo') # Raises IOError: not opened for writing Initial state: ```ruby -strio = StringIO.new(TEXT, 'w') +strio = StringIO.new(TEXT.dup, 'w') strio.pos # => 0 # Beginning of stream. strio.string # => "" # Initially truncated. ``` + May be written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: ```ruby -strio = StringIO.new(TEXT, 'w') strio.write('foobar') strio.string # => "foobar" @@ -168,15 +168,33 @@ strio.gets # Raises IOError: not opened for reading Initial state: ```ruby -strio = StringIO.new('foo', 'r+') -strio.pos # => 0 # Beginning-of-stream. -strio.string # => "foo" # Not truncated. +strio = StringIO.new('foobar', 'r+') +strio.pos # => 0 # Beginning-of-stream. +strio.string # => "foobar" # Not truncated. ``` May be read or written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: ```ruby +strio.gets # => "foobar" + +strio.rewind +strio.gets # => "foobar" +strio.pos = 3 +strio.gets # => "bar" + +strio.rewind +strio.write('FOO') +strio.string # => "FOObar" + +strio.pos = 3 +strio.write('BAR') +strio.string # => "FOOBAR" + +strio.pos = 9 +strio.write('baz') +strio.string # => "FOOBAR\u0000\u0000\u0000baz" ``` From f5e729a8182089a79c0d7f971b97000a595d4350 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 5 Nov 2025 22:42:15 +0000 Subject: [PATCH 08/34] More on read/write modes --- doc/stringio/stringio.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index e6bdb5a6..0bb1db4d 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -197,9 +197,33 @@ strio.write('baz') strio.string # => "FOOBAR\u0000\u0000\u0000baz" ``` - #### `'w+'`: Read/Write (Initial Truncate) +Initial state: + +```ruby +strio = StringIO.new('foo', 'w+') +strio.pos # => 0 # Beginning-of-stream. +strio.string # => "" # Truncated. +``` + +May be read or written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: + + +```ruby +strio.write('bar') +strio.string # => "bar" +strio.write('foo') +strio.string # => "barfoo" +strio.rewind +strio.write('FOO') +strio.string # => "FOOfoo" +strio.write('BAR') +strio.string # => "FOOBAR" +strio.pos = 10 +strio.write('baz') +strio.string # => "FOOBAR\u0000\u0000\u0000\u0000baz" +``` #### `'a+'`: Read/Append From 2e20381502523c2b3a3a6b97c44c4f9343592fd1 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 17:26:51 +0000 Subject: [PATCH 09/34] More on read/write modes --- doc/stringio/stringio.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 0bb1db4d..139bf488 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -59,7 +59,7 @@ DATA = "\u9990\u9991\u9992\u9993\u9994" | 'a': append-only | No | Error | - | End only | End | | 'r+': read/write | No | Anywhere | 0 | Anywhere | 0 | | 'w+': read-write | Yes | Anywhere | 0 | Anywhere | 0 | -| 'a+': read/append | No | Anywhere | End | End only | End | +| 'a+': read/append | No | Anywhere | 0 | End only | End | #### `'r'`: Read-Only @@ -98,7 +98,7 @@ strio.write('foo') # Raises IOError: not opened for writing Initial state: ```ruby -strio = StringIO.new(TEXT.dup, 'w') +strio = StringIO.new('foo', 'w') strio.pos # => 0 # Beginning of stream. strio.string # => "" # Initially truncated. ``` @@ -213,13 +213,17 @@ May be read or written anywhere (even past end-of-stream); see #rewind, #pos=, # ```ruby strio.write('bar') strio.string # => "bar" + strio.write('foo') strio.string # => "barfoo" + strio.rewind strio.write('FOO') strio.string # => "FOOfoo" + strio.write('BAR') strio.string # => "FOOBAR" + strio.pos = 10 strio.write('baz') strio.string # => "FOOBAR\u0000\u0000\u0000\u0000baz" @@ -227,6 +231,28 @@ strio.string # => "FOOBAR\u0000\u0000\u0000\u0000baz" #### `'a+'`: Read/Append +Initial state: + +```ruby +strio = StringIO.new('foo', 'a+') +strio.pos# => 0 # Beginning-of-stream. +strio.string # => "foo" # Not truncated. +``` + +May be written only at the end; #rewind, #pos=, #seek do not affect writing: + +```ruby +strio.write('bar') +strio.string # => "foobar" +strio.write('baz') +strio.string # => "foobarbaz" + +strio.rewind +strio.pos = 400 +strio.seek(1, IO::SEEK_CUR) +strio.write('bat') +strio.string # => "foobarbazbat" +``` ### Data Mode From 2029244bebb3151d4ef9b9fedf1c3cb31b661001 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 17:42:22 +0000 Subject: [PATCH 10/34] More on read/write modes --- doc/stringio/stringio.md | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 139bf488..b14d839b 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -173,28 +173,29 @@ strio.pos # => 0 # Beginning-of-stream. strio.string # => "foobar" # Not truncated. ``` -May be read or written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: +May be written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: ```ruby -strio.gets # => "foobar" - -strio.rewind -strio.gets # => "foobar" - -strio.pos = 3 -strio.gets # => "bar" - -strio.rewind strio.write('FOO') strio.string # => "FOObar" - -strio.pos = 3 strio.write('BAR') strio.string # => "FOOBAR" +strio.write('BAZ') +strio.string # => "FOOBARBAZ" +strio.pos = 12 +strio.write('BAT') +strio.string # => "FOOBARBAZ\u0000\u0000\u0000BAT" # Null padded. +``` -strio.pos = 9 -strio.write('baz') -strio.string # => "FOOBAR\u0000\u0000\u0000baz" +May be read anywhere: + +```ruby +strio.pos = 0 +strio.gets(3) # => "FOO" +strio.pos = 6 +strio.gets(3) # => "BAZ" +strio.pos = 400 +strio.gets(3) # => nil ``` #### `'w+'`: Read/Write (Initial Truncate) From 0ba2ea37c919a6c46dd567df1f8438df0cc6c643 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 17:55:31 +0000 Subject: [PATCH 11/34] More on read/write modes --- doc/stringio/stringio.md | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index b14d839b..784066a0 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -204,30 +204,38 @@ Initial state: ```ruby strio = StringIO.new('foo', 'w+') -strio.pos # => 0 # Beginning-of-stream. +strio.pos # => 0 # Beginning-of-stream. strio.string # => "" # Truncated. ``` -May be read or written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: +May be written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: ```ruby -strio.write('bar') -strio.string # => "bar" - -strio.write('foo') -strio.string # => "barfoo" - +strio.write('foobar') +strio.string # => "foobar" strio.rewind strio.write('FOO') -strio.string # => "FOOfoo" - +strio.string # => "FOObar" strio.write('BAR') strio.string # => "FOOBAR" +strio.write('BAZ') +strio.string # => "FOOBARBAZ" +strio.pos = 12 +strio.write('BAT') +strio.string # => "FOOBARBAZ\u0000\u0000\u0000BAT" # Null-padded. +``` -strio.pos = 10 -strio.write('baz') -strio.string # => "FOOBAR\u0000\u0000\u0000\u0000baz" +May be read anywhere: + +```ruby +strio.rewind +strio.gets(3) # => "FOO" +strio.gets(3) # => "BAR" +strio.pos = 12 +strio.gets(3) # => "BAT" +strio.pos = 400 +strio.gets(3) # => nil ``` #### `'a+'`: Read/Append @@ -247,7 +255,6 @@ strio.write('bar') strio.string # => "foobar" strio.write('baz') strio.string # => "foobarbaz" - strio.rewind strio.pos = 400 strio.seek(1, IO::SEEK_CUR) @@ -255,6 +262,17 @@ strio.write('bat') strio.string # => "foobarbazbat" ``` +May be read anywhere: + +```ruby +strio.rewind +strio.gets(3) # => "foo" +strio.gets(3) # => "bar" +strio.pos = 9 +strio.gets(3) # => "bat" +strio.pos = 400 +strio.gets(3) # => nil +``` ### Data Mode ### Encodings From b80c9c1a27140d6ebce439325b4943c2f0ebb868 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 18:14:56 +0000 Subject: [PATCH 12/34] More on read/write modes --- doc/stringio/stringio.md | 55 +++++++++++++--------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 784066a0..eaf65ebe 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -66,25 +66,18 @@ DATA = "\u9990\u9991\u9992\u9993\u9994" Initial state: ```ruby -strio = StringIO.new(TEXT, 'r') -strio.pos # => 0 # Beginning of stream. -strio.string.size == 0 # => false # Not truncated. +strio = StringIO.new('foobarbaz', 'r') +strio.pos # => 0 # Beginning-of-stream. +strio.string # => "foobarbaz" # Not truncated. ``` -May be written anywhere; see #rewind, #pos=, #seek: +May be read anywhere: ```ruby -strio.gets # => "First line\n" -strio.gets # => "Second line\n" - -strio.rewind -strio.gets # => "First line\n" - -strio.pos = 1 -strio.gets # => "irst line\n" - -strio.seek(1, IO::SEEK_CUR) -strio.gets # => "econd line\n" +strio.gets(3) # => "foo" +strio.gets(3) # => "bar" +strio.pos = 9 +strio.gets(3) # => nil ``` May not be written: @@ -93,7 +86,7 @@ May not be written: strio.write('foo') # Raises IOError: not opened for writing ``` -#### `'w'`: Write-Only (Initial Truncate) +#### `'w'`: Write-Only Initial state: @@ -103,27 +96,20 @@ strio.pos # => 0 # Beginning of stream. strio.string # => "" # Initially truncated. ``` -May be written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: +May be written anywhere (even past end-of-stream): ```ruby strio.write('foobar') strio.string # => "foobar" - strio.rewind strio.write('FOO') strio.string # => "FOObar" - strio.pos = 3 strio.write('BAR') strio.string # => "FOOBAR" - -strio.seek(1, IO::SEEK_CUR) +strio.pos = 9 strio.write('baz') -strio.string # => "FOOBAR\u0000baz" # Null-padded. - -strio.pos = 20 -strio.write('bat') -strio.string # => "FOOBAR\u0000baz\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000bat" +strio.string # => "FOOBAR\u0000\u0000\u0000baz" # Null-padded. ``` May not be read: @@ -138,21 +124,18 @@ Initial state: ```ruby strio = StringIO.new('foo', 'a') -strio.pos # => 0 # Beginning-of-stream. +strio.pos # => 0 # Beginning-of-stream. strio.string # => "foo" # Not truncated. ``` -May be written only at the end; #rewind, #pos=, #seek do not affect writing: +May be written only at the end; position does not affect writing: ```ruby strio.write('bar') strio.string # => "foobar" strio.write('baz') strio.string # => "foobarbaz" - -strio.rewind strio.pos = 400 -strio.seek(1, IO::SEEK_CUR) strio.write('bat') strio.string # => "foobarbazbat" ``` @@ -173,7 +156,7 @@ strio.pos # => 0 # Beginning-of-stream. strio.string # => "foobar" # Not truncated. ``` -May be written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: +May be written anywhere (even past end-of-stream): ```ruby strio.write('FOO') @@ -208,7 +191,7 @@ strio.pos # => 0 # Beginning-of-stream. strio.string # => "" # Truncated. ``` -May be written anywhere (even past end-of-stream); see #rewind, #pos=, #seek: +May be written anywhere (even past end-of-stream): ```ruby @@ -244,20 +227,18 @@ Initial state: ```ruby strio = StringIO.new('foo', 'a+') -strio.pos# => 0 # Beginning-of-stream. +strio.pos # => 0 # Beginning-of-stream. strio.string # => "foo" # Not truncated. ``` -May be written only at the end; #rewind, #pos=, #seek do not affect writing: +May be written only at the end; #rewind; position does not affect writing: ```ruby strio.write('bar') strio.string # => "foobar" strio.write('baz') strio.string # => "foobarbaz" -strio.rewind strio.pos = 400 -strio.seek(1, IO::SEEK_CUR) strio.write('bat') strio.string # => "foobarbazbat" ``` From d793ff2cffbb73d1aed337c9ecbd4f8918cf26a1 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 19:19:05 +0000 Subject: [PATCH 13/34] More on data mode --- doc/stringio/stringio.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index eaf65ebe..5f8312a9 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -256,6 +256,33 @@ strio.gets(3) # => nil ``` ### Data Mode +To specify whether the stream is to be treated as text or as binary data, +either of the following may be suffixed to any of the read/write modes above: + +- `'t'`: Text; + sets the default external encoding to Encoding::UTF_8. +- `'b'`: Binary; + sets the default external encoding to Encoding::ASCII_8BIT. + +If neither is given, the stream defaults to text data. + +Examples: + +```ruby +strio = StringIO.new(TEXT, 'rt') +strio.external_encoding # => # +strio = StringIO.new(DATA, 'rb') +strio.external_encoding # => #``` + +When the data mode is specified, the read/write mode may not be omitted: + +```ruby +StringIO.new('DATA', 'b') # Raises ArgumentError: invalid access mode b +``` + +A text stream may be changed to binary by calling instance method #binmode; +a binary stream may not be changed to text. + ### Encodings ### Position From 6a563b4b3f9770ecac5fb24a1dd06c43cd0c5eb1 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 19:41:11 +0000 Subject: [PATCH 14/34] More on data mode --- doc/stringio/stringio.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 5f8312a9..cba4a00e 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -193,7 +193,6 @@ strio.string # => "" # Truncated. May be written anywhere (even past end-of-stream): - ```ruby strio.write('foobar') strio.string # => "foobar" @@ -257,7 +256,7 @@ strio.gets(3) # => nil ### Data Mode To specify whether the stream is to be treated as text or as binary data, -either of the following may be suffixed to any of the read/write modes above: +either of the following may be suffixed to any of the string read/write modes above: - `'t'`: Text; sets the default external encoding to Encoding::UTF_8. From 62a6d4756fd69044cb50642f56e26ee9ef521baa Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 20:42:15 +0000 Subject: [PATCH 15/34] More on I/O --- doc/stringio/stringio.md | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index cba4a00e..88d6d2a8 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -296,7 +296,7 @@ a binary stream may not be changed to text. ### Reading -You can read immediately from the stream using these instance methods: +You can read from the stream using these instance methods: - #getbyte: reads and returns the next byte. - #getc: reads and returns the next character. @@ -319,15 +319,15 @@ This instance method is useful in a multi-threaded application: You can write to the stream, advancing the position, using these instance methods: -- #putc: write the given character. -- #write: write the given strings. +- #putc: writes the given character. +- #write: writes the given strings. You can "unshift" to the stream using these instance methods; each writes at the current position, without advancing the position, so that the written data is next to be read. -- #ungetbyte: unshift the given byte. -- #ungetc.: unshift the given character. +- #ungetbyte: unshifts the given byte. +- #ungetc.: unshifts the given character. This instance method truncates the stream to the given size: @@ -335,14 +335,32 @@ This instance method truncates the stream to the given size: ## Line \IO +- #gets: reads and returns the next line. +- #each_line: reads each remaining line, passing it to the block +- #readlines: reads the remaining data the stream and returns an array of its lines. +- [Kernel#puts][kernel#puts]: writes given objects, each followed by newline. +- [Kernel#readline][kernel#readline]: like #gets, but raises an exception if at end-of-stream. + ## Character \IO +- #each_char: reads each remaining character, passing it to the block. +- #getc: reads and returns the next character. +- #putc: writes the given character. +- #ungetc.: unshifts the given character. + ## Byte \IO +- #each_byte: reads each remaining byte, passing it to the block. +- #getbyte: reads and returns the next byte. +- #ungetbyte: unshifts the given byte. + ## Codepoint \IO +- #each_codepoint: reads each remaining codepoint, passing it to the block. -[class io]: https://docs.ruby-lang.org/en/master/IO.html +[class io]: https://docs.ruby-lang.org/en/master/IO.html +[kernel#puts]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-puts +[kernel#readline]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-readline [data mode]: rdoc-ref:StringIO@Data+Mode [encodings]: rdoc-ref:StringIO@Encodings @@ -351,3 +369,10 @@ This instance method truncates the stream to the given size: [open/closed streams]: rdoc-ref:StringIO@Open-2FClosed+Streams [position]: rdoc-ref:StringIO@Position [read/write mode]: rdoc-ref:StringIO@Read-2FWrite+Mode + + From f9045e8483790111f5d073c00e1d4d41b12fff58 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 20:45:09 +0000 Subject: [PATCH 16/34] More on I/O --- doc/stringio/stringio.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 88d6d2a8..a5cf884e 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -303,6 +303,7 @@ You can read from the stream using these instance methods: - #gets: reads and returns the next line. - #read: reads and returns the remaining data in the stream. - #readlines: reads the remaining data the stream and returns an array of its lines. +- [Kernel#readline][kernel#readline]: like #gets, but raises an exception if at end-of-stream. You can iterate over the stream using these instance methods: @@ -321,6 +322,7 @@ You can write to the stream, advancing the position, using these instance method - #putc: writes the given character. - #write: writes the given strings. +- [Kernel#puts][kernel#puts]: writes given objects, each followed by newline. You can "unshift" to the stream using these instance methods; each writes at the current position, without advancing the position, From 222150a3b7f3536a3cd57d6718d8c5c1b09adb34 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 22:54:47 +0000 Subject: [PATCH 17/34] Doc for open/closed streams --- doc/stringio/stringio.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index a5cf884e..a98f4df7 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -284,14 +284,40 @@ a binary stream may not be changed to text. ### Encodings +[TODO] + ### Position +[TODO] + ### Line Number +[TODO] + ### Open/Closed Streams +A new stream is open for either reading or writing, and may be open for both; +see [Read/Write Mode][read/write mode]. + +Each of these methods initializes the read/write mode for a new or re-initialized stream: + +- ::new(string = '', mode = 'r+'): returns a new stream. +- ::open(string = '', mode = 'r+'): passes a new stream to the block. +- #reopen(string = '', mode = 'r+'): re-initializes the stream. + +Other relevant methods: + +- #close: closes the stream for both reading and writing. +- #close_read: closes the stream for reading. +- #close_write: closes the stream for writing. +- #closed?: returns whether the stream is closed for both reading and writing. +- #closed_read?: returns whether the stream is closed for reading. +- #closed_write?: returns whether the stream is closed for writing. + ### End-of-Stream +[TODO] + ## Basic Stream \IO ### Reading From bfa1cf10675ea6d25cc225d5c924d208fca502e1 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 23:10:31 +0000 Subject: [PATCH 18/34] More on basic IO --- doc/stringio/stringio.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index a98f4df7..ab8cd9e3 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -326,8 +326,8 @@ You can read from the stream using these instance methods: - #getbyte: reads and returns the next byte. - #getc: reads and returns the next character. -- #gets: reads and returns the next line. -- #read: reads and returns the remaining data in the stream. +- #gets: reads and returns all or part of the next line. +- #read: reads and returns all or part of the remaining data in the stream. - #readlines: reads the remaining data the stream and returns an array of its lines. - [Kernel#readline][kernel#readline]: like #gets, but raises an exception if at end-of-stream. @@ -336,30 +336,30 @@ You can iterate over the stream using these instance methods: - #each_byte: reads each remaining byte, passing it to the block. - #each_char: reads each remaining character, passing it to the block. - #each_codepoint: reads each remaining codepoint, passing it to the block. -- #each_line: reads each remaining line, passing it to the block +- #each_line: reads all or part of each remaining line, passing the read string to the block This instance method is useful in a multi-threaded application: -- #pread. - +- #pread: reads and returns all or part of the stream. + ### Writing You can write to the stream, advancing the position, using these instance methods: -- #putc: writes the given character. -- #write: writes the given strings. -- [Kernel#puts][kernel#puts]: writes given objects, each followed by newline. +- #putc(character): writes a given character. +- #write(*objects): writes the given objects as strings. +- [Kernel#puts][kernel#puts](*objects): writes given objects as strings, each followed by newline. You can "unshift" to the stream using these instance methods; each writes at the current position, without advancing the position, so that the written data is next to be read. -- #ungetbyte: unshifts the given byte. -- #ungetc.: unshifts the given character. +- #ungetbyte(byte): unshifts the given byte. +- #ungetc(character): unshifts the given character. -This instance method truncates the stream to the given size: +One more writing method: -- #truncate. +- #truncate(size): truncates the stream's string to the given size. ## Line \IO From 627fac386ea4783c0f5e9020b1e5b8a90a9fd4a4 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Thu, 6 Nov 2025 23:17:47 +0000 Subject: [PATCH 19/34] More on IO --- doc/stringio/stringio.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index ab8cd9e3..ab861e2e 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -347,8 +347,8 @@ This instance method is useful in a multi-threaded application: You can write to the stream, advancing the position, using these instance methods: - #putc(character): writes a given character. -- #write(*objects): writes the given objects as strings. -- [Kernel#puts][kernel#puts](*objects): writes given objects as strings, each followed by newline. +- #write: writes the given objects as strings. +- [Kernel#puts][kernel#puts] writes given objects as strings, each followed by newline. You can "unshift" to the stream using these instance methods; each writes at the current position, without advancing the position, @@ -363,27 +363,44 @@ One more writing method: ## Line \IO +Reading: + - #gets: reads and returns the next line. - #each_line: reads each remaining line, passing it to the block - #readlines: reads the remaining data the stream and returns an array of its lines. -- [Kernel#puts][kernel#puts]: writes given objects, each followed by newline. - [Kernel#readline][kernel#readline]: like #gets, but raises an exception if at end-of-stream. +Writing: + +- [Kernel#puts][kernel#puts]: writes given objects, each followed by newline. + ## Character \IO +Reading: + - #each_char: reads each remaining character, passing it to the block. - #getc: reads and returns the next character. + +Writing: + - #putc: writes the given character. - #ungetc.: unshifts the given character. ## Byte \IO +Reading: + - #each_byte: reads each remaining byte, passing it to the block. - #getbyte: reads and returns the next byte. + +Writing: + - #ungetbyte: unshifts the given byte. ## Codepoint \IO +Reading: + - #each_codepoint: reads each remaining codepoint, passing it to the block. [class io]: https://docs.ruby-lang.org/en/master/IO.html From bb5dd4654c6cc4b9957329135863b9c9e77689d8 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Fri, 7 Nov 2025 00:42:44 +0000 Subject: [PATCH 20/34] Doc for position --- doc/stringio/stringio.md | 110 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index ab861e2e..12ee72f8 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -288,7 +288,107 @@ a binary stream may not be changed to text. ### Position -[TODO] +A stream has a _position_, and integer offset (in characters, not bytes) into the stream. +The initial position of a stream is zero. + +A couple of methods: + +- #pos: returns the position. +- #pos=: sets the position. + +Except for #pread, a read method (see [Basic Reading][basic reading]) +begins reading at the current position. + +Except for #pread, a read method advances the position past the read substring. + +Examples: + +```ruby +strio = StringIO.new(TEXT) +strio.string # => "First line\nSecond line\n\nFourth line\nFifth line\n" +strio.pos # => 0 +strio.getc # => "F" +strio.pos # => 1 +strio.gets # => "irst line\n" +strio.pos # => 11 +strio.pos = 24 +strio.gets # => "Fourth line\n" +strio.pos # => 36 +``` + +These write methods advance the position to the end of the written substring: + +- #putc(character): writes a given character. +- #write: writes the given objects as strings. +- [Kernel#puts][kernel#puts] writes given objects as strings, each followed by newline. + +Examples: + +```ruby +strio = StringIO.new('foo') +strio.pos # => 0 +strio.putc('b') +strio.string # => "boo" +strio.pos # => 1 +strio.write('r') +strio.string # => "bro" +strio.pos # => 2 +strio.puts('ew') +strio.string # => "brew\n" +strio.pos # => 5 +strio.pos = 8 +strio.write('foo') +strio.string # => "brew\n\u0000\u0000\u0000foo" +strio.pos # => 11 +``` + +An iterator method sets the position to end-of-stream: + +```ruby +strio.pos = 0 +strio.each_char {|char| nil } +strio.pos # => 11 +``` + +Each of these methods writes _before_ the current position, and decrements the position +so that the written data is next to be read: + +- #ungetbyte(byte): unshifts the given byte. +- #ungetc(character): unshifts the given character. + +Examples: + +```ruby +strio = StringIO.new('foo') +strio.pos = 2 +strio.ungetc('x') +strio.pos # => 1 +strio.string # => "fxo" +strio.ungetc('x') +strio.pos # => 0 +strio.string # => "xxo" +``` + +Each of these method sets the position to zero: + +- #rewind: sets the position to zero. +- #truncate(size): truncates the stream's string to the given size. + +Examples: + +```ruby +strio = StringIO.new('foobar') +strio.truncate(3) +strio.pos # => 0 +strio.string # => "foo" +strio.truncate(0) +strio.pos # => 0 +strio.string # => "" +``` + +This method sets the position: + +- #seek: sets the position. ### Line Number @@ -320,7 +420,7 @@ Other relevant methods: ## Basic Stream \IO -### Reading +### Basic Reading You can read from the stream using these instance methods: @@ -342,7 +442,7 @@ This instance method is useful in a multi-threaded application: - #pread: reads and returns all or part of the stream. -### Writing +### Basic Writing You can write to the stream, advancing the position, using these instance methods: @@ -351,7 +451,7 @@ You can write to the stream, advancing the position, using these instance method - [Kernel#puts][kernel#puts] writes given objects as strings, each followed by newline. You can "unshift" to the stream using these instance methods; -each writes at the current position, without advancing the position, +each writes _before_ the current position, and decrements the position so that the written data is next to be read. - #ungetbyte(byte): unshifts the given byte. @@ -407,6 +507,8 @@ Reading: [kernel#puts]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-puts [kernel#readline]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-readline +[basic reading]: rdoc-ref:StringIO@Basic+Reading +[basic writing]: rdoc-ref:StringIO@Basic+Writing [data mode]: rdoc-ref:StringIO@Data+Mode [encodings]: rdoc-ref:StringIO@Encodings [end-of-stream]: rdoc-ref:StringIO@End-of-Stream From ce8b199d41064fc36c1239d7504a46981245e55a Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Fri, 7 Nov 2025 00:47:47 +0000 Subject: [PATCH 21/34] Doc for position --- doc/stringio/stringio.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 12ee72f8..81f0b2af 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -288,7 +288,7 @@ a binary stream may not be changed to text. ### Position -A stream has a _position_, and integer offset (in characters, not bytes) into the stream. +A stream has a _position_, and integer offset (in bytes) into the stream. The initial position of a stream is zero. A couple of methods: From 60cf281ad91a2de3ec98e723969b2b5b8d406ec1 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Sat, 8 Nov 2025 19:20:40 +0000 Subject: [PATCH 22/34] More on position --- doc/stringio/stringio.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 81f0b2af..d876a691 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -31,7 +31,7 @@ Examples on this page assume that \StringIO has been required: require 'stringio' ``` -And that these constants have been defined: +And that this constant has been defined: ``` TEXT = < # -strio = StringIO.new(DATA, 'rb') +data = "\u9990\u9991\u9992\u9993\u9994" +strio = StringIO.new(data, 'rb') strio.external_encoding # => #``` When the data mode is specified, the read/write mode may not be omitted: ```ruby -StringIO.new('DATA', 'b') # Raises ArgumentError: invalid access mode b +StringIO.new(data, 'b') # Raises ArgumentError: invalid access mode b ``` A text stream may be changed to binary by calling instance method #binmode; @@ -296,7 +294,7 @@ A couple of methods: - #pos: returns the position. - #pos=: sets the position. -Except for #pread, a read method (see [Basic Reading][basic reading]) +Except for #pread, a stream reading method (see [Basic Reading][basic reading]) begins reading at the current position. Except for #pread, a read method advances the position past the read substring. @@ -314,6 +312,14 @@ strio.pos # => 11 strio.pos = 24 strio.gets # => "Fourth line\n" strio.pos # => 36 + +strio = StringIO.new('тест') # Four 2-byte characters. +strio.pos = 0 # At first byte of first character. +strio.read # => "тест" +strio.pos = 1 # At second byte of first character. +strio.read # => "\x82ест" +strio.pos = 2 # At first of second character. +strio.read # => "ест" ``` These write methods advance the position to the end of the written substring: From dbb78321dc3a2b323625052970097d72ebdcc7db Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Sat, 8 Nov 2025 20:13:26 +0000 Subject: [PATCH 23/34] More on position --- doc/stringio/stringio.md | 55 +++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index d876a691..2997f113 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -289,10 +289,29 @@ a binary stream may not be changed to text. A stream has a _position_, and integer offset (in bytes) into the stream. The initial position of a stream is zero. -A couple of methods: +#### Getting and Setting the Position + +Each of these methods gets or sets the position, without otherwise changing the stream: - #pos: returns the position. - #pos=: sets the position. +- #rewind: sets the position to zero. +- #seek: sets the position. + +Examples: + +```ruby +strio = StringIO.new('foobar') +strio.pos # => 0 +strio.pos = 3 +strio.pos # => 3 +strio.rewind +strio.pos # => 0 +strio.seek(0, IO::SEEK_END) +strio.pos # => 6 +``` + +#### Position Before and After Reading Except for #pread, a stream reading method (see [Basic Reading][basic reading]) begins reading at the current position. @@ -320,9 +339,19 @@ strio.pos = 1 # At second byte of first character. strio.read # => "\x82ест" strio.pos = 2 # At first of second character. strio.read # => "ест" + +strio = StringIO.new(TEXT) +strio.pos = 15 +a = [] +strio.each_line {|line| a.push(line) } +a # => ["nd line\n", "\n", "Fourth line\n", "Fifth line\n"] +strio.pos # => 47 ## End-of-stream. ``` -These write methods advance the position to the end of the written substring: +#### Position Before and After Writing + +Each of these methods begins writing at the current position, +and advances the position to the end of the written substring: - #putc(character): writes a given character. - #write: writes the given objects as strings. @@ -348,14 +377,6 @@ strio.string # => "brew\n\u0000\u0000\u0000foo" strio.pos # => 11 ``` -An iterator method sets the position to end-of-stream: - -```ruby -strio.pos = 0 -strio.each_char {|char| nil } -strio.pos # => 11 -``` - Each of these methods writes _before_ the current position, and decrements the position so that the written data is next to be read: @@ -375,27 +396,25 @@ strio.pos # => 0 strio.string # => "xxo" ``` -Each of these method sets the position to zero: -- #rewind: sets the position to zero. +This method does not affect the position: + - #truncate(size): truncates the stream's string to the given size. Examples: ```ruby strio = StringIO.new('foobar') -strio.truncate(3) strio.pos # => 0 +strio.truncate(3) strio.string # => "foo" -strio.truncate(0) strio.pos # => 0 +strio.pos = 500 +strio.truncate(0) strio.string # => "" +strio.pos # => 500 ``` -This method sets the position: - -- #seek: sets the position. - ### Line Number [TODO] From 22b00d579581dba66f506c804c9ce79afb26b551 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Sat, 8 Nov 2025 20:31:33 +0000 Subject: [PATCH 24/34] More on position and encodings --- doc/stringio/stringio.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 2997f113..2c68475e 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -282,7 +282,12 @@ a binary stream may not be changed to text. ### Encodings -[TODO] +- #external_encoding: returns the current encoding of the stream. +- #internal_encoding: returns +nil+. +- #set_encoding: sets the encoding for the stream. +- #set_encoding_by_bom: sets the encoding for the stream to the stream's BOM (byte order mark). + +- data mode ### Position @@ -291,6 +296,12 @@ The initial position of a stream is zero. #### Getting and Setting the Position +Each of these methods initializes (to zero) the position of a new or re-initialized stream: + +- ::new(string = '', mode = 'r+'): returns a new stream. +- ::open(string = '', mode = 'r+'): passes a new stream to the block. +- #reopen(string = '', mode = 'r+'): re-initializes the stream. + Each of these methods gets or sets the position, without otherwise changing the stream: - #pos: returns the position. @@ -546,5 +557,6 @@ Reading: TODO: - Add File constants (e.g., File::RDONLY) to Data Mode section. +- Review the summary table, as regards position. --> From e1dbd022416c413b13da853bd42aacca0ba6a7bf Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Sun, 9 Nov 2025 01:07:51 +0000 Subject: [PATCH 25/34] Doc for line number --- doc/stringio/stringio.md | 91 ++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 13 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 2c68475e..a3ac58d9 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -1,5 +1,5 @@ \Class \StringIO supports accessing a string as a stream, -similar in some ways to [class IO][class io]. +similar in some ways to [class IO][io class]. You can create a \StingIO instance using: @@ -256,9 +256,9 @@ To specify whether the stream is to be treated as text or as binary data, either of the following may be suffixed to any of the string read/write modes above: - `'t'`: Text; - sets the default external encoding to Encoding::UTF_8. + initializes the encoding as Encoding::UTF_8. - `'b'`: Binary; - sets the default external encoding to Encoding::ASCII_8BIT. + initializes the encoding as Encoding::ASCII_8BIT. If neither is given, the stream defaults to text data. @@ -282,12 +282,33 @@ a binary stream may not be changed to text. ### Encodings -- #external_encoding: returns the current encoding of the stream. -- #internal_encoding: returns +nil+. +A stream has an encoding; see the [encodings document][encodings document]. + +The initial encoding for a new or re-opened stream depends on its [data mode][data mode]: + +- Text: `Encoding::UTF_8`. +- Binary: `Encoding::ASCII_8BIT`. + +These instance methods are relevant: + +- #external_encoding: returns the current encoding of the stream as an `Encoding` object. +- #internal_encoding: returns +nil+; a stream does not have an internal encoding. - #set_encoding: sets the encoding for the stream. - #set_encoding_by_bom: sets the encoding for the stream to the stream's BOM (byte order mark). -- data mode +Examples: + +```ruby +strio = StringIO.new('foo', 'rt') # Text mode. +strio.external_encoding # => # +data = "\u9990\u9991\u9992\u9993\u9994" +strio = StringIO.new(data, 'rb') # Binary mode. +strio.external_encoding # => # +strio = StringIO.new('foo') +strio.external_encoding # => # +strio.set_encoding('US-ASCII') +strio.external_encoding # => # +``` ### Position @@ -296,7 +317,7 @@ The initial position of a stream is zero. #### Getting and Setting the Position -Each of these methods initializes (to zero) the position of a new or re-initialized stream: +Each of these methods initializes (to zero) the position of a new or re-opened stream: - ::new(string = '', mode = 'r+'): returns a new stream. - ::open(string = '', mode = 'r+'): passes a new stream to the block. @@ -407,7 +428,6 @@ strio.pos # => 0 strio.string # => "xxo" ``` - This method does not affect the position: - #truncate(size): truncates the stream's string to the given size. @@ -428,14 +448,58 @@ strio.pos # => 500 ### Line Number -[TODO] +A stream has a line number, which initially is zero: + +- Method #lineno returns the line number. +- Method #lineno= sets the line number. + +The line number can be affected by reading (but never by writing); +in general, the line number is incremented each time the record separator (default: `"\n"`) is read. + +Examples: + +```ruby +strio = StringIO.new(TEXT) +strio.string # => "First line\nSecond line\n\nFourth line\nFifth line\n" +strio.lineno # => 0 +strio.gets # => "First line\n" +strio.lineno # => 1 +strio.getc # => "S" +strio.lineno # => 1 +strio.gets # => "econd line\n" +strio.lineno # => 2 +strio.gets # => "\n" +strio.lineno # => 3 +strio.gets # => "Fourth line\n" +strio.lineno # => 4 +``` + +Setting the position does not affect the line number: + +```ruby +strio.pos = 0 +strio.lineno # => 4 +strio.gets # => "First line\n" +strio.pos # => 11 +strio.lineno # => 5 +``` + +And setting the line number does not affect the position: + +```ruby +strio.lineno = 10 +strio.pos # => 11 +strio.gets # => "Second line\n" +strio.lineno # => 11 +strio.pos # => 23 +``` ### Open/Closed Streams A new stream is open for either reading or writing, and may be open for both; see [Read/Write Mode][read/write mode]. -Each of these methods initializes the read/write mode for a new or re-initialized stream: +Each of these methods initializes the read/write mode for a new or re-opened stream: - ::new(string = '', mode = 'r+'): returns a new stream. - ::open(string = '', mode = 'r+'): passes a new stream to the block. @@ -539,9 +603,10 @@ Reading: - #each_codepoint: reads each remaining codepoint, passing it to the block. -[class io]: https://docs.ruby-lang.org/en/master/IO.html -[kernel#puts]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-puts -[kernel#readline]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-readline +[encodings document]: https://docs.ruby-lang.org/en/master/encodings_rdoc.html +[io class]: https://docs.ruby-lang.org/en/master/IO.html +[kernel#puts]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-puts +[kernel#readline]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-readline [basic reading]: rdoc-ref:StringIO@Basic+Reading [basic writing]: rdoc-ref:StringIO@Basic+Writing From ce8bba684b3e18d86c54384ad89bced7eef55973 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Sun, 9 Nov 2025 01:13:56 +0000 Subject: [PATCH 26/34] More on position --- doc/stringio/stringio.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index a3ac58d9..82541e95 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -323,8 +323,9 @@ Each of these methods initializes (to zero) the position of a new or re-opened s - ::open(string = '', mode = 'r+'): passes a new stream to the block. - #reopen(string = '', mode = 'r+'): re-initializes the stream. -Each of these methods gets or sets the position, without otherwise changing the stream: +Each of these methods queries, gets, or sets the position, without otherwise changing the stream: +- #eof?: returns whether the position is at end-of-stream. - #pos: returns the position. - #pos=: sets the position. - #rewind: sets the position to zero. @@ -334,13 +335,15 @@ Examples: ```ruby strio = StringIO.new('foobar') -strio.pos # => 0 +strio.pos # => 0 strio.pos = 3 -strio.pos # => 3 +strio.pos # => 3 +strio.eof? # => false strio.rewind -strio.pos # => 0 +strio.pos # => 0 strio.seek(0, IO::SEEK_END) -strio.pos # => 6 +strio.pos # => 6 +strio.eof? # => true ``` #### Position Before and After Reading @@ -514,10 +517,6 @@ Other relevant methods: - #closed_read?: returns whether the stream is closed for reading. - #closed_write?: returns whether the stream is closed for writing. -### End-of-Stream - -[TODO] - ## Basic Stream \IO ### Basic Reading From 752de6c792cfde345e67e8d5dc1f545745f46df8 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Sun, 9 Nov 2025 01:22:16 +0000 Subject: [PATCH 27/34] Fix summary table --- doc/stringio/stringio.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 82541e95..d66d7a56 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -18,8 +18,8 @@ Like an \IO stream, a \StringIO stream has certain properties: see [Position][position]. - **Line number**: a special, line-oriented, "position" (different from the position mentioned above); see [Line Number][line number]. -- **Open/closed**: whether the stream is open or closed, for reading or writing. - see [Open/Closed Streams][open/closed streams]. + - **Open/closed**: whether the stream is open or closed, for reading or writing. + see [Open/Closed Streams][open/closed streams]. - **End-of-stream**: whether the position is at the end of the stream; see [End-of-Stream][end-of-stream]. @@ -49,14 +49,14 @@ EOT #### Summary -| Mode | Truncate? | Read | Read Pos | Write | Write Pos | -|:--------------------------:|:---------:|:--------:|:--------:|:--------:|:---------:| -| 'r': read-only | No | Anywhere | 0 | Error | - | -| 'w': write-only | Yes | Error | - | Anywhere | 0 | -| 'a': append-only | No | Error | - | End only | End | -| 'r+': read/write | No | Anywhere | 0 | Anywhere | 0 | -| 'w+': read-write | Yes | Anywhere | 0 | Anywhere | 0 | -| 'a+': read/append | No | Anywhere | 0 | End only | End | +| Mode | Truncate? | Read | Write | +|:--------------------------:|:---------:|:--------:|:--------:| +| 'r': read-only | No | Anywhere | Error | +| 'w': write-only | Yes | Error | Anywhere | +| 'a': append-only | No | Error | End only | +| 'r+': read/write | No | Anywhere | Anywhere | +| 'w+': read-write | Yes | Anywhere | Anywhere | +| 'a+': read/append | No | Anywhere | End only | #### `'r'`: Read-Only @@ -621,6 +621,5 @@ Reading: TODO: - Add File constants (e.g., File::RDONLY) to Data Mode section. -- Review the summary table, as regards position. --> From a37597b2101c1f20ff1d714b28756b44e0bc99ab Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Sun, 9 Nov 2025 01:44:51 +0000 Subject: [PATCH 28/34] More on initial clear --- doc/stringio/stringio.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index d66d7a56..7fa4ba43 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -49,14 +49,14 @@ EOT #### Summary -| Mode | Truncate? | Read | Write | -|:--------------------------:|:---------:|:--------:|:--------:| -| 'r': read-only | No | Anywhere | Error | -| 'w': write-only | Yes | Error | Anywhere | -| 'a': append-only | No | Error | End only | -| 'r+': read/write | No | Anywhere | Anywhere | -| 'w+': read-write | Yes | Anywhere | Anywhere | -| 'a+': read/append | No | Anywhere | End only | +| Mode | Initial Clear? | Read | Write | +|:--------------------------:|:--------------:|:--------:|:--------:| +| 'r': read-only | No | Anywhere | Error | +| 'w': write-only | Yes | Error | Anywhere | +| 'a': append-only | No | Error | End only | +| 'r+': read/write | No | Anywhere | Anywhere | +| 'w+': read-write | Yes | Anywhere | Anywhere | +| 'a+': read/append | No | Anywhere | End only | #### `'r'`: Read-Only @@ -65,7 +65,7 @@ Initial state: ```ruby strio = StringIO.new('foobarbaz', 'r') strio.pos # => 0 # Beginning-of-stream. -strio.string # => "foobarbaz" # Not truncated. +strio.string # => "foobarbaz" # Not cleared. ``` May be read anywhere: @@ -90,7 +90,7 @@ Initial state: ```ruby strio = StringIO.new('foo', 'w') strio.pos # => 0 # Beginning of stream. -strio.string # => "" # Initially truncated. +strio.string # => "" # Initially cleared. ``` May be written anywhere (even past end-of-stream): @@ -122,7 +122,7 @@ Initial state: ```ruby strio = StringIO.new('foo', 'a') strio.pos # => 0 # Beginning-of-stream. -strio.string # => "foo" # Not truncated. +strio.string # => "foo" # Not cleared. ``` May be written only at the end; position does not affect writing: @@ -150,7 +150,7 @@ Initial state: ```ruby strio = StringIO.new('foobar', 'r+') strio.pos # => 0 # Beginning-of-stream. -strio.string # => "foobar" # Not truncated. +strio.string # => "foobar" # Not cleared. ``` May be written anywhere (even past end-of-stream): @@ -178,7 +178,7 @@ strio.pos = 400 strio.gets(3) # => nil ``` -#### `'w+'`: Read/Write (Initial Truncate) +#### `'w+'`: Read/Write (Initially Clear) Initial state: @@ -224,7 +224,7 @@ Initial state: ```ruby strio = StringIO.new('foo', 'a+') strio.pos # => 0 # Beginning-of-stream. -strio.string # => "foo" # Not truncated. +strio.string # => "foo" # Not cleared. ``` May be written only at the end; #rewind; position does not affect writing: From a3a7926d3df956740b4b7f875596167ff93abdff Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Sun, 9 Nov 2025 01:56:53 +0000 Subject: [PATCH 29/34] Tune up TODOs --- doc/stringio/stringio.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 7fa4ba43..42d3cab6 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -617,9 +617,16 @@ Reading: [position]: rdoc-ref:StringIO@Position [read/write mode]: rdoc-ref:StringIO@Read-2FWrite+Mode + From b4f18948186652c261c2aad138152752002203c3 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Mon, 10 Nov 2025 22:45:23 +0000 Subject: [PATCH 30/34] Doc for BOM --- doc/stringio/stringio.md | 75 ++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 18 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 42d3cab6..cd9fed36 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -18,10 +18,10 @@ Like an \IO stream, a \StringIO stream has certain properties: see [Position][position]. - **Line number**: a special, line-oriented, "position" (different from the position mentioned above); see [Line Number][line number]. - - **Open/closed**: whether the stream is open or closed, for reading or writing. - see [Open/Closed Streams][open/closed streams]. -- **End-of-stream**: whether the position is at the end of the stream; - see [End-of-Stream][end-of-stream]. +- **Open/closed**: whether the stream is open or closed, for reading or writing. + see [Open/Closed Streams][open/closed streams]. +- **BOM**: byte mark order; + see [Byte Order Mark][byte order mark]. ## About the Examples @@ -517,6 +517,45 @@ Other relevant methods: - #closed_read?: returns whether the stream is closed for reading. - #closed_write?: returns whether the stream is closed for writing. +### BOM (Byte Order Mark) + +The string provided for ::new, ::open, or #reopen +may contain an optional [BOM][bom] (byte order mark) at the beginning of the string; +the BOM can affect the stream's encoding. + +The BOM (if provided): + +- Is stored as part of the stream's string. +- Does _not_ immediately affect the encoding. +- Is _initially_ considered part of the stream. + +```ruby + +utf8_bom = "\xEF\xBB\xBF" +string = utf8_bom + 'foo' +string.bytes # => [239, 187, 191, 102, 111, 111] +strio.string.bytes.take(3) # => [239, 187, 191] # The BOM. +strio = StringIO.new(string, 'rb') +strio.string.bytes # => [239, 187, 191, 102, 111, 111] # BOM is part of the stored string. +strio.external_encoding # => # # Default for a binary stream. +strio.gets # => "\xEF\xBB\xBFfoo" # BOM is part of the stream. +``` + +You can call instance method #set_encoding_by_bom to "activate" the stored BOM; +after doing so the BOM: + +- Is _still_ stored as part of the stream's string. +- _Determines_ (and may have changed) the stream's encoding. +- Is _no longer_ considered part of the stream. + +```ruby +strio.set_encoding_by_bom +strio.string.bytes # => [239, 187, 191, 102, 111, 111] # BOM is still part of the stored string. +strio.external_encoding # => # # The new encoding. +strio.rewind # => 0 +strio.gets # => "foo" # BOM is not part of the stream. +``` + ## Basic Stream \IO ### Basic Reading @@ -602,20 +641,22 @@ Reading: - #each_codepoint: reads each remaining codepoint, passing it to the block. +[bom]: https://en.wikipedia.org/wiki/Byte_order_mark [encodings document]: https://docs.ruby-lang.org/en/master/encodings_rdoc.html [io class]: https://docs.ruby-lang.org/en/master/IO.html [kernel#puts]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-puts [kernel#readline]: https://docs.ruby-lang.org/en/master/Kernel.html#method-i-readline -[basic reading]: rdoc-ref:StringIO@Basic+Reading -[basic writing]: rdoc-ref:StringIO@Basic+Writing -[data mode]: rdoc-ref:StringIO@Data+Mode -[encodings]: rdoc-ref:StringIO@Encodings -[end-of-stream]: rdoc-ref:StringIO@End-of-Stream -[line number]: rdoc-ref:StringIO@Line+Number -[open/closed streams]: rdoc-ref:StringIO@Open-2FClosed+Streams -[position]: rdoc-ref:StringIO@Position -[read/write mode]: rdoc-ref:StringIO@Read-2FWrite+Mode +[basic reading]: rdoc-ref:StringIO@Basic+Reading +[basic writing]: rdoc-ref:StringIO@Basic+Writing +[bom (byte order mark)]: rdoc-ref:StringIO@BOM+-28Byte+Order+Mark-29 +[data mode]: rdoc-ref:StringIO@Data+Mode +[encodings]: rdoc-ref:StringIO@Encodings +[end-of-stream]: rdoc-ref:StringIO@End-of-Stream +[line number]: rdoc-ref:StringIO@Line+Number +[open/closed streams]: rdoc-ref:StringIO@Open-2FClosed+Streams +[position]: rdoc-ref:StringIO@Position +[read/write mode]: rdoc-ref:StringIO@Read-2FWrite+Mode From 8f9e46e95b889056e27baf2a5701e918eaf0b662 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Tue, 11 Nov 2025 18:31:48 +0000 Subject: [PATCH 31/34] Document file constants --- doc/stringio/stringio.md | 54 ++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index cd9fed36..79bf45a6 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -58,8 +58,23 @@ EOT | 'w+': read-write | Yes | Anywhere | Anywhere | | 'a+': read/append | No | Anywhere | End only | +Each section below describes a read/write mode. + +Any of the modes may be given as a string or as file constants; +example: + +```ruby +strio = StringIO.new('foo', 'a') +strio = StringIO.new('foo', File::WRONLY | File::APPEND) +``` + #### `'r'`: Read-Only +Mode specified as one of: + +- String: `'r'`. +- Constant: `File::RDONLY`. + Initial state: ```ruby @@ -85,6 +100,11 @@ strio.write('foo') # Raises IOError: not opened for writing #### `'w'`: Write-Only +Mode specified as one of: + +- String: `'w'`. +- Constant: `File::WRONLY`. + Initial state: ```ruby @@ -117,6 +137,11 @@ strio.read # Raises IOError: not opened for reading #### `'a'`: Append-Only +Mode specified as one of: + +- String: `'a'`. +- Constant: `File::WRONLY | File::APPEND`. + Initial state: ```ruby @@ -145,6 +170,11 @@ strio.gets # Raises IOError: not opened for reading #### `'r+'`: Read/Write +Mode specified as one of: + +- String: `'r+'`. +- Constant: `File::RDRW`. + Initial state: ```ruby @@ -180,6 +210,11 @@ strio.gets(3) # => nil #### `'w+'`: Read/Write (Initially Clear) +Mode specified as one of: + +- String: `'w+'`. +- Constant: `File::RDWR | File::TRUNC`. + Initial state: ```ruby @@ -219,6 +254,11 @@ strio.gets(3) # => nil #### `'a+'`: Read/Append +Mode specified as one of: + +- String: `'a+'`. +- Constant: `File::RDWR | File::APPEND`. + Initial state: ```ruby @@ -250,6 +290,7 @@ strio.gets(3) # => "bat" strio.pos = 400 strio.gets(3) # => nil ``` + ### Data Mode To specify whether the stream is to be treated as text or as binary data, @@ -530,7 +571,6 @@ The BOM (if provided): - Is _initially_ considered part of the stream. ```ruby - utf8_bom = "\xEF\xBB\xBF" string = utf8_bom + 'foo' string.bytes # => [239, 187, 191, 102, 111, 111] @@ -657,15 +697,3 @@ Reading: [open/closed streams]: rdoc-ref:StringIO@Open-2FClosed+Streams [position]: rdoc-ref:StringIO@Position [read/write mode]: rdoc-ref:StringIO@Read-2FWrite+Mode - - - From 1b2d3bd21b21c1e01c1f024ad9096537125461fd Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Wed, 12 Nov 2025 04:15:12 +0000 Subject: [PATCH 32/34] [DOC] Fix typos --- doc/stringio/stringio.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index 79bf45a6..ca80dca6 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -1,7 +1,7 @@ \Class \StringIO supports accessing a string as a stream, similar in some ways to [class IO][io class]. -You can create a \StingIO instance using: +You can create a \StringIO instance using: - StringIO.new(string): returns a new \StringIO object containing the given string. - StringIO.open(string): passes a new \StringIO object to the given block. @@ -21,7 +21,7 @@ Like an \IO stream, a \StringIO stream has certain properties: - **Open/closed**: whether the stream is open or closed, for reading or writing. see [Open/Closed Streams][open/closed streams]. - **BOM**: byte mark order; - see [Byte Order Mark][byte order mark]. + see [Byte Order Mark][bom (byte order mark)]. ## About the Examples From 4b838584bd9803580a7e9c8090aaf6458d3dab46 Mon Sep 17 00:00:00 2001 From: BurdetteLamar Date: Fri, 14 Nov 2025 16:59:32 +0000 Subject: [PATCH 33/34] Add ruby to fenced code blocks --- doc/stringio/stringio.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index ca80dca6..bd330874 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -27,13 +27,13 @@ Like an \IO stream, a \StringIO stream has certain properties: Examples on this page assume that \StringIO has been required: -``` +```ruby require 'stringio' ``` And that this constant has been defined: -``` +```ruby TEXT = < Date: Wed, 3 Dec 2025 20:09:23 +0000 Subject: [PATCH 34/34] Respond to reviews --- doc/stringio/stringio.md | 41 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/doc/stringio/stringio.md b/doc/stringio/stringio.md index bd330874..aebfa6d6 100644 --- a/doc/stringio/stringio.md +++ b/doc/stringio/stringio.md @@ -3,8 +3,8 @@ similar in some ways to [class IO][io class]. You can create a \StringIO instance using: -- StringIO.new(string): returns a new \StringIO object containing the given string. -- StringIO.open(string): passes a new \StringIO object to the given block. +- StringIO.new: returns a new \StringIO object containing the given string. +- StringIO.open: passes a new \StringIO object to the given block. Like an \IO stream, a \StringIO stream has certain properties: @@ -310,7 +310,8 @@ strio = StringIO.new('foo', 'rt') strio.external_encoding # => # data = "\u9990\u9991\u9992\u9993\u9994" strio = StringIO.new(data, 'rb') -strio.external_encoding # => #``` +strio.external_encoding # => # +``` When the data mode is specified, the read/write mode may not be omitted: @@ -360,9 +361,9 @@ The initial position of a stream is zero. Each of these methods initializes (to zero) the position of a new or re-opened stream: -- ::new(string = '', mode = 'r+'): returns a new stream. -- ::open(string = '', mode = 'r+'): passes a new stream to the block. -- #reopen(string = '', mode = 'r+'): re-initializes the stream. +- ::new: returns a new stream. +- ::open: passes a new stream to the block. +- #reopen: re-initializes the stream. Each of these methods queries, gets, or sets the position, without otherwise changing the stream: @@ -429,9 +430,9 @@ strio.pos # => 47 ## End-of-stream. Each of these methods begins writing at the current position, and advances the position to the end of the written substring: -- #putc(character): writes a given character. +- #putc: writes the given character. - #write: writes the given objects as strings. -- [Kernel#puts][kernel#puts] writes given objects as strings, each followed by newline. +- [Kernel#puts][kernel#puts]: writes given objects as strings, each followed by newline. Examples: @@ -456,8 +457,8 @@ strio.pos # => 11 Each of these methods writes _before_ the current position, and decrements the position so that the written data is next to be read: -- #ungetbyte(byte): unshifts the given byte. -- #ungetc(character): unshifts the given character. +- #ungetbyte: unshifts the given byte. +- #ungetc: unshifts the given character. Examples: @@ -474,7 +475,7 @@ strio.string # => "xxo" This method does not affect the position: -- #truncate(size): truncates the stream's string to the given size. +- #truncate: truncates the stream's string to the given size. Examples: @@ -545,9 +546,9 @@ see [Read/Write Mode][read/write mode]. Each of these methods initializes the read/write mode for a new or re-opened stream: -- ::new(string = '', mode = 'r+'): returns a new stream. -- ::open(string = '', mode = 'r+'): passes a new stream to the block. -- #reopen(string = '', mode = 'r+'): re-initializes the stream. +- ::new: returns a new stream. +- ::open: passes a new stream to the block. +- #reopen: re-initializes the stream. Other relevant methods: @@ -624,7 +625,7 @@ This instance method is useful in a multi-threaded application: You can write to the stream, advancing the position, using these instance methods: -- #putc(character): writes a given character. +- #putc: writes a given character. - #write: writes the given objects as strings. - [Kernel#puts][kernel#puts] writes given objects as strings, each followed by newline. @@ -632,21 +633,21 @@ You can "unshift" to the stream using these instance methods; each writes _before_ the current position, and decrements the position so that the written data is next to be read. -- #ungetbyte(byte): unshifts the given byte. -- #ungetc(character): unshifts the given character. +- #ungetbyte: unshifts the given byte. +- #ungetc: unshifts the given character. One more writing method: -- #truncate(size): truncates the stream's string to the given size. +- #truncate: truncates the stream's string to the given size. ## Line \IO Reading: - #gets: reads and returns the next line. -- #each_line: reads each remaining line, passing it to the block -- #readlines: reads the remaining data the stream and returns an array of its lines. - [Kernel#readline][kernel#readline]: like #gets, but raises an exception if at end-of-stream. +- #readlines: reads the remaining data the stream and returns an array of its lines. +- #each_line: reads each remaining line, passing it to the block Writing: