go-ruby-stringio

Ruby's StringIO — an in-memory IO over a String buffer — in pure Go, MRI-compatible, no cgo.

pure Go · zero cgo StringIO r / w / a · r+/w+/a+ gets · paragraph mode getc · getbyte seek + NUL-pad typed IOError / EOFError ungetc / ungetbyte MRI byte-exact 100% coverage 6 arches · 3 OSes
Documentation GitHub
Documentation (MkDocs Material + mike) License: BSD-3-Clause Go 1.26.4+ Coverage 100%

go-ruby-stringio is a pure-Go (no cgo) reimplementation of Ruby's StringIO — an in-memory IO whose backing store is a String buffer. It reproduces MRI's StringIO semantics exactly: a read/write cursor over a byte buffer, mode-gated access (r/w/a and the r+/w+/a+ variants), gets line splitting with separators, byte limits and paragraph mode, character/byte iteration, seek-past-end NUL padding, and the EOFError / IOError / ArgumentError raises MRI emits — without any Ruby runtime. It is bound into go-embedded-ruby by rbgo as a native module just like go-ruby-regexp and go-ruby-erb — differential-tested against MRI, 100% coverage, CI green across 6 arches and 3 OSes.

Modes ready

r / w / a and the r+ / w+ / a+ read-write variants, with w/w+ truncating the seed string and append mode writing at the end regardless of the cursor.

Reading ready

Byte-oriented read(n) / read (nil for a length read at EOF), gets with a separator, a byte limit, and paragraph mode (gets("")), readline / readlines / each_line, character-oriented getc / each_char / readchar, and byte-oriented getbyte / each_byte / readbyte.

Writing ready

write / <<, puts / print / printf, putc, and seek-past-end writes that extend and NUL-pad the buffer exactly like MRI.

Positioning ready

pos / pos= / tell, seek (SEEK_SET / CUR / END), rewind, with a negative position raising Errno::EINVAL.

Content & state ready

string / string=, truncate (shrink or grow with NUL-pad), size / length, eof?, close / closed?, flush, lineno / lineno=, and ungetc / ungetbyte prepending at the start of the buffer.

Exact MRI raises & coverage ready

Read on a write-only stream, write on a read-only stream, or any op on a closed stream raise IOError; readline/readchar/readbyte at EOF raise EOFError; a negative read length raises ArgumentError. A corpus of StringIO programs is run by ruby and reproduced here byte-for-byte; 100% coverage, green across six 64-bit arches and three OSes.

A faithful port of Ruby's StringIO in pure Go, cgo disabled, so it cross-compiles and embeds anywhere. It reproduces the read/write cursor, mode gating (r/w/a/r+/w+/a+), gets line splitting, character/byte iteration, seek-past-end NUL padding, and the exact EOFError / IOError / ArgumentError raises — validated differentially against the system ruby binary. It is a standalone, reusable module bound into the sibling org github.com/go-embedded-ruby.