Class: StringIO
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Instance Chain:
self,
Enumerable,
::IO::generic_readable,
::IO::generic_writable
|
|
| Inherits: | Object |
| Defined in: | ext/stringio/stringio.c |
Overview
\IO streams for strings, with access similar to IO; see IO.
About the Examples
Examples on this page assume that \StringIO has been required:
require 'stringio'
And that these constants have been defined:
TEXT = <<EOT
First line
Second line
Fourth line
Fifth line
EOT
RUSSIAN = 'тест'
DATA = "\u9990\u9991\u9992\u9993\u9994"
Constant Summary
-
MAX_LENGTH =
# File 'ext/stringio/stringio.c', line 2167
Maximum length that a
StringIOinstance can holdLONG2NUM(LONG_MAX)
-
VERSION =
# File 'ext/stringio/stringio.c', line 2161
The version string
rb_str_new_cstr(STRINGIO_VERSION)
Class Method Summary
-
.open(string = '', mode = 'r+') ⇒ StringIO
Creates new StringIO instance by calling
StringIO.new(string, mode). - .new(*args) constructor Internal use only
Instance Attribute Summary
-
#closed? ⇒ Boolean
readonly
Returns whether
selfis closed for both reading and writing: -
#closed_read? ⇒ Boolean
readonly
Returns whether
selfis closed for reading: -
#closed_write? ⇒ Boolean
readonly
Returns whether
selfis closed for writing: -
#eof? ⇒ Boolean
(also: #eof?)
readonly
Returns whether
selfis positioned at end-of-stream: -
#eof? ⇒ Boolean
readonly
Alias for #eof.
-
#lineno ⇒ current_line_number
rw
Returns the current line number in
self; see Line Number. -
#lineno=(new_line_number) ⇒ new_line_number
rw
Sets the current line number in
selfto the givennew_line_number; see Line Number. -
#pos ⇒ stream_position
rw
Returns the current position (in bytes); see Position.
-
#pos=(new_position) ⇒ new_position
rw
Sets the current position (in bytes); see Position.
-
#string ⇒ String
rw
Returns underlying string:
-
#string=(other_string) ⇒ other_string
rw
Replaces the stored string with
other_string, and sets the position to zero; returnsother_string: - #tty? ⇒ Boolean readonly
Instance Method Summary
-
#binmode ⇒ self
Sets the data mode in
selfto binary mode; see Data Mode. -
#close ⇒ nil
Closes
selffor both reading and writing; returnsnil: -
#close_read ⇒ nil
Closes
selffor reading; closed-write setting remains unchanged; returnsnil: -
#close_write ⇒ nil
Closes
selffor writing; closed-read setting remains unchanged; returnsnil: -
#each_line(sep = $/, chomp: false) {|line| ... } ⇒ self
(also: #each_line)
With a block given calls the block with each remaining line (see "Position" below) in the stream; returns
self. -
#each_byte {|byte| ... } ⇒ self
With a block given, calls the block with each remaining byte in the stream; positions the stream at end-of-file; returns
self: -
#each_char {|char| ... } ⇒ self
With a block given, calls the block with each remaining character in the stream; positions the stream at end-of-file; returns
self: -
#each_codepoint {|codepoint| ... } ⇒ self
With a block given, calls the block with each successive codepoint from self; sets the position to end-of-stream; returns
self. -
#each_line(sep = $/, chomp: false) {|line| ... } ⇒ self
Alias for #each.
-
#external_encoding ⇒ Encoding?
Returns an Encoding object that represents the encoding of the string; see
Encoding: - #fcntl
- #fileno
- #flush
- #fsync
-
#getbyte ⇒ Integer?
Reads and returns the next integer byte (not character) from the stream:
-
#getc ⇒ character, ...
Reads and returns the next character (or byte; see below) from the stream:
-
#gets(sep = $/, chomp: false) ⇒ String?
Reads and returns a line from the stream; returns
nilif at end-of-stream. -
#new(string = '', mode = 'r+') ⇒ StringIO
constructor
Returns a new StringIO instance formed from #string and
mode; the instance should be closed when no longer needed: -
#internal_encoding ⇒ nil
Returns
nil; for compatibility with::IO. - #isatty
-
#length ⇒ Integer
(also: #size)
Returns the size of the buffer string.
- #pid
-
#pread(maxlen, offset) ⇒ String
See
IO#pread. -
#putc(obj) ⇒ Object
See
IO#putc. -
#read([length [, outbuf]]) ⇒ String, ...
See
IO#read. -
#readlines(sep = $/, chomp: false) ⇒ Array
See
IO#readlines. -
#reopen(other, mode = 'r+') ⇒ self
Reinitializes the stream with the given
other(string orStringIO) andmode; seeIO.new: -
#rewind ⇒ 0
Sets the current position and line number to zero; see Position and Line Number.
-
#seek(offset, whence = SEEK_SET) ⇒ 0
Sets the current position to the given integer
offset(in bytes), with respect to a given constantwhence; see Position. -
#set_encoding(ext_enc, [int_enc[, opt]]) ⇒ strio
Specify the encoding of the
StringIOas ext_enc. -
#set_encoding_by_bom ⇒ strio?
Sets the encoding according to the BOM (Byte Order Mark) in the string.
-
#size ⇒ Integer
Alias for #length.
-
#sync ⇒ true
Returns
true; implemented only for compatibility with other stream classes. - #sync=
- #tell
-
#truncate(integer) ⇒ 0
Truncates the buffer string to at most integer bytes.
-
#ungetbyte(byte) ⇒ nil
Pushes back (“unshifts”) an 8-bit byte onto the stream; see Byte IO.
-
#ungetc(character) ⇒ nil
Pushes back (“unshifts”) a character or integer onto the stream; see Character IO.
-
#write(string, ...) ⇒ Integer
Appends the given string to the underlying buffer string.
- #initialize_copy(orig) Internal use only
::IO::generic_readable - Included
| #read_nonblock | Similar to #read, but raises |
| #readbyte | |
| #readchar | Like #getc, but raises an exception if already at end-of-stream; see Character IO. |
| #readline | Reads a line as with |
| #readpartial | Alias for IO::generic_readable#sysread. |
| #sysread | Similar to #read, but raises |
::IO::generic_writable - Included
Constructor Details
.new(*args)
# File 'ext/stringio/stringio.c', line 414
static VALUE
strio_s_new(int argc, VALUE *argv, VALUE klass)
{
if (rb_block_given_p()) {
VALUE cname = rb_obj_as_string(klass);
rb_warn("%"PRIsVALUE"::new() does not take block; use %"PRIsVALUE"::open() instead",
cname, cname);
}
return rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
}
#new(string = '', mode = 'r+') ⇒ StringIO
Returns a new StringIO instance formed from #string and mode; the instance should be closed when no longer needed:
strio = StringIO.new
strio.string # => ""
strio.closed_read? # => false
strio.closed_write? # => false
strio.close
If #string is frozen, the default mode is 'r':
strio = StringIO.new('foo'.freeze)
strio.string # => "foo"
strio.closed_read? # => false
strio.closed_write? # => true
strio.close
Argument mode must be a valid Access Mode, which may be a string or an integer constant:
StringIO.new('foo', 'w+')
StringIO.new('foo', File::RDONLY)
Related: .open (passes the StringIO object to the block; closes the object automatically on block exit).
# File 'ext/stringio/stringio.c', line 255
static VALUE
strio_initialize(int argc, VALUE *argv, VALUE self)
{
struct StringIO *ptr = check_strio(self);
if (!ptr) {
DATA_PTR(self) = ptr = strio_alloc();
}
rb_call_super(0, 0);
return strio_init(argc, argv, ptr, self);
}
Class Method Details
.open(string = '', mode = 'r+') ⇒ StringIO
.open(string = '', mode = 'r+') {|strio| ... } ⇒ Object
StringIO
.open(string = '', mode = 'r+') {|strio| ... } ⇒ Object
Creates new StringIO instance by calling StringIO.new(string, mode).
With no block given, returns the new instance:
strio = StringIO.open # => #<StringIO>
With a block given, calls the block with the new instance and returns the block’s value; closes the instance on block exit:
StringIO.open('foo') {|strio| strio.string.upcase } # => "FOO"
Related: .new.
# File 'ext/stringio/stringio.c', line 405
static VALUE
strio_s_open(int argc, VALUE *argv, VALUE klass)
{
VALUE obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
if (!rb_block_given_p()) return obj;
return rb_ensure(rb_yield, obj, strio_finalize, obj);
}
Instance Attribute Details
#closed? ⇒ Boolean (readonly)
Returns whether self is closed for both reading and writing:
strio = StringIO.new
strio.closed? # => false # Open for reading and writing.
strio.close_read
strio.closed? # => false # Still open for writing.
strio.close_write
strio.closed? # => true # Now closed for both.
Related: #closed_read?, #closed_write?.
# File 'ext/stringio/stringio.c', line 640
static VALUE
strio_closed(VALUE self)
{
StringIO(self);
if (!CLOSED(self)) return Qfalse;
return Qtrue;
}
#closed_read? ⇒ Boolean (readonly)
Returns whether self is closed for reading:
strio = StringIO.new
strio.closed_read? # => false
strio.close_read
strio.closed_read? # => true
Related: #closed?, #closed_write?, #close_read.
# File 'ext/stringio/stringio.c', line 661
static VALUE
strio_closed_read(VALUE self)
{
StringIO(self);
if (READABLE(self)) return Qfalse;
return Qtrue;
}
#closed_write? ⇒ Boolean (readonly)
Returns whether self is closed for writing:
strio = StringIO.new
strio.closed_write? # => false
strio.close_write
strio.closed_write? # => true
Related: #close_write, #closed?, #closed_read?.
# File 'ext/stringio/stringio.c', line 682
static VALUE
strio_closed_write(VALUE self)
{
StringIO(self);
if (WRITABLE(self)) return Qfalse;
return Qtrue;
}
#eof? ⇒ Boolean (readonly) Also known as: #eof?
# File 'ext/stringio/stringio.c', line 715
static VALUE
strio_eof(VALUE self)
{
if (strio_to_read(self)) return Qfalse;
return Qtrue;
}
#eof? ⇒ Boolean (readonly)
#eof? ⇒ Boolean
Boolean (readonly)
#eof? ⇒ Boolean
Alias for #eof.
#lineno ⇒ current_line_number (rw)
Returns the current line number in self; see Line Number.
# File 'ext/stringio/stringio.c', line 752
static VALUE
strio_get_lineno(VALUE self)
{
return LONG2NUM(StringIO(self)->lineno);
}
#lineno=(new_line_number) ⇒ new_line_number (rw)
Sets the current line number in self to the given new_line_number; see Line Number.
# File 'ext/stringio/stringio.c', line 765
static VALUE
strio_set_lineno(VALUE self, VALUE lineno)
{
StringIO(self)->lineno = NUM2LONG(lineno);
return lineno;
}
#pos ⇒ stream_position (rw)
Returns the current position (in bytes); see Position.
# File 'ext/stringio/stringio.c', line 840
static VALUE
strio_get_pos(VALUE self)
{
return LONG2NUM(StringIO(self)->pos);
}
#pos=(new_position) ⇒ new_position (rw)
Sets the current position (in bytes); see Position.
# File 'ext/stringio/stringio.c', line 853
static VALUE
strio_set_pos(VALUE self, VALUE pos)
{
struct StringIO *ptr = StringIO(self);
long p = NUM2LONG(pos);
if (p < 0) {
error_inval(0);
}
ptr->pos = p;
return pos;
}
#string ⇒ String (rw)
# File 'ext/stringio/stringio.c', line 507
static VALUE
strio_get_string(VALUE self)
{
return StringIO(self)->string;
}
#string=(other_string) ⇒ other_string (rw)
# File 'ext/stringio/stringio.c', line 533
static VALUE
strio_set_string(VALUE self, VALUE string)
{
struct StringIO *ptr = StringIO(self);
rb_io_taint_check(self);
ptr->flags &= ~FMODE_READWRITE;
StringValue(string);
ptr->flags = readonly_string_p(string) ? FMODE_READABLE : FMODE_READWRITE;
ptr->pos = 0;
ptr->lineno = 0;
RB_OBJ_WRITE(self, &ptr->string, string);
return string;
}
#tty? ⇒ Boolean (readonly)
[ GitHub ]
Instance Method Details
#binmode ⇒ self
Sets the data mode in self to binary mode; see Data Mode.
# File 'ext/stringio/stringio.c', line 780
static VALUE
strio_binmode(VALUE self)
{
struct StringIO *ptr = StringIO(self);
rb_encoding *enc = rb_ascii8bit_encoding();
ptr->enc = enc;
if (WRITABLE(self)) {
rb_enc_associate(ptr->string, enc);
}
return self;
}
#close ⇒ nil
Closes self for both reading and writing; returns nil:
strio = StringIO.new
strio.closed? # => false
strio.close # => nil
strio.closed? # => true
strio.read # Raises IOError: not opened for reading
strio.write # Raises IOError: not opened for writing
Related: #close_read, #close_write, #closed?.
# File 'ext/stringio/stringio.c', line 563
static VALUE
strio_close(VALUE self)
{
StringIO(self);
RBASIC(self)->flags &= ~STRIO_READWRITE;
return Qnil;
}
#close_read ⇒ nil
Closes self for reading; closed-write setting remains unchanged; returns nil:
strio = StringIO.new
strio.closed_read? # => false
strio.close_read # => nil
strio.closed_read? # => true
strio.closed_write? # => false
strio.read # Raises IOError: not opened for reading
Related: #close, #close_write.
# File 'ext/stringio/stringio.c', line 588
static VALUE
strio_close_read(VALUE self)
{
struct StringIO *ptr = StringIO(self);
if (!(ptr->flags & FMODE_READABLE)) {
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
}
RBASIC(self)->flags &= ~STRIO_READABLE;
return Qnil;
}
#close_write ⇒ nil
Closes self for writing; closed-read setting remains unchanged; returns nil:
strio = StringIO.new
strio.closed_write? # => false
strio.close_write # => nil
strio.closed_write? # => true
strio.closed_read? # => false
strio.write('foo') # Raises IOError: not opened for writing
Related: #close, #close_read, #closed_write?.
# File 'ext/stringio/stringio.c', line 614
static VALUE
strio_close_write(VALUE self)
{
struct StringIO *ptr = StringIO(self);
if (!(ptr->flags & FMODE_WRITABLE)) {
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
}
RBASIC(self)->flags &= ~STRIO_WRITABLE;
return Qnil;
}
#each_line(sep = $/, chomp: false) {|line| ... } ⇒ self
#each_line(limit, chomp: false) {|line| ... } ⇒ self
#each_line(sep, limit, chomp: false) {|line| ... } ⇒ self
Also known as: #each_line
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.
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 #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, #each honors two special record separators;
see Special Line Separators.
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.
Related: #each_byte, #each_char, #each_codepoint.
# File 'ext/stringio/stringio.c', line 1641
static VALUE
strio_each(int argc, VALUE *argv, VALUE self)
{
VALUE line;
struct StringIO *ptr = readable(self);
struct getline_arg arg;
RETURN_ENUMERATOR(self, argc, argv);
if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
}
while (!NIL_P(line = strio_getline(&arg, ptr))) {
rb_yield(line);
}
return self;
}
#each_byte {|byte| ... } ⇒ self
With a block given, calls the block with each remaining byte in the stream; positions the stream at end-of-file; returns self:
bytes = []
strio = StringIO.new('hello') # Five 1-byte characters.
strio.each_byte {|byte| bytes.push(byte) }
strio.eof? # => true
bytes # => [104, 101, 108, 108, 111]
bytes = []
strio = StringIO.new('тест') # Four 2-byte characters.
strio.each_byte {|byte| bytes.push(byte) }
bytes # => [209, 130, 208, 181, 209, 129, 209, 130]
bytes = []
strio = StringIO.new('こんにちは') # Five 3-byte characters.
strio.each_byte {|byte| bytes.push(byte) }
bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]
The position in the stream matters:
bytes = []
strio = StringIO.new('こんにちは')
strio.getc # => "こ"
strio.pos # => 3 # 3-byte character was read.
strio.each_byte {|byte| bytes.push(byte) }
bytes # => [227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]
If at end-of-file, does not call the block:
strio.eof? # => true
strio.each_byte {|byte| fail 'Boo!' }
strio.eof? # => true
With no block given, returns a new Enumerator.
Related: #each_char, #each_codepoint, #each_line.
# File 'ext/stringio/stringio.c', line 951
static VALUE
strio_each_byte(VALUE self)
{
struct StringIO *ptr;
RETURN_ENUMERATOR(self, 0, 0);
while ((ptr = strio_to_read(self)) != NULL) {
char c = RSTRING_PTR(ptr->string)[ptr->pos++];
rb_yield(CHR2FIX(c));
}
return self;
}
#each_char {|char| ... } ⇒ self
With a block given, calls the block with each remaining character in the stream; positions the stream at end-of-file; returns self:
chars = []
strio = StringIO.new('hello')
strio.each_char {|char| chars.push(char) }
strio.eof? # => true
chars # => ["h", "e", "l", "l", "o"]
chars = []
strio = StringIO.new('тест')
strio.each_char {|char| chars.push(char) }
chars # => ["т", "е", "с", "т"]
chars = []
strio = StringIO.new('こんにちは')
strio.each_char {|char| chars.push(char) }
chars # => ["こ", "ん", "に", "ち", "は"]
Stream position matters:
chars = []
strio = StringIO.new('こんにちは')
strio.getc # => "こ"
strio.pos # => 3 # 3-byte character was read.
strio.each_char {|char| chars.push(char) }
chars # => ["ん", "に", "ち", "は"]
When at end-of-stream does not call the block:
strio.eof? # => true
strio.each_char {|char| fail 'Boo!' }
strio.eof? # => true
With no block given, returns a new Enumerator.
Related: #each_byte, #each_codepoint, #each_line.
# File 'ext/stringio/stringio.c', line 1178
static VALUE
strio_each_char(VALUE self)
{
VALUE c;
RETURN_ENUMERATOR(self, 0, 0);
while (!NIL_P(c = strio_getc(self))) {
rb_yield(c);
}
return self;
}
#each_codepoint {|codepoint| ... } ⇒ self
With a block given, calls the block with each successive codepoint from self; sets the position to end-of-stream; returns self.
Each codepoint is the integer value for a character; returns self:
codepoints = []
strio = StringIO.new('hello')
strio.each_codepoint {|codepoint| codepoints.push(codepoint) }
strio.eof? # => true
codepoints # => [104, 101, 108, 108, 111]
codepoints = []
strio = StringIO.new('тест')
strio.each_codepoint {|codepoint| codepoints.push(codepoint) }
codepoints # => [1090, 1077, 1089, 1090]
codepoints = []
strio = StringIO.new('こんにちは')
strio.each_codepoint {|codepoint| codepoints.push(codepoint) }
codepoints # => [12371, 12435, 12395, 12385, 12399]
Position in the stream matters:
codepoints = []
strio = StringIO.new('こんにちは')
strio.getc # => "こ"
strio.pos # => 3
strio.each_codepoint {|codepoint| codepoints.push(codepoint) }
codepoints # => [12435, 12395, 12385, 12399]
When at end-of-stream, the block is not called:
strio.eof? # => true
strio.each_codepoint {|codepoint| fail 'Boo!' }
strio.eof? # => true
With no block given, returns a new Enumerator.
Related: #each_byte, #each_char, #each_line.
# File 'ext/stringio/stringio.c', line 1199
static VALUE
strio_each_codepoint(VALUE self)
{
struct StringIO *ptr;
rb_encoding *enc;
unsigned int c;
int n;
RETURN_ENUMERATOR(self, 0, 0);
ptr = readable(self);
enc = get_enc(ptr);
while ((ptr = strio_to_read(self)) != NULL) {
c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos,
RSTRING_END(ptr->string), &n, enc);
ptr->pos += n;
rb_yield(UINT2NUM(c));
}
return self;
}
#each_line(sep = $/, chomp: false) {|line| ... } ⇒ self
#each_line(limit, chomp: false) {|line| ... } ⇒ self
#each_line(sep, limit, chomp: false) {|line| ... } ⇒ self
self
#each_line(limit, chomp: false) {|line| ... } ⇒ self
#each_line(sep, limit, chomp: false) {|line| ... } ⇒ self
Alias for #each.
#external_encoding ⇒ Encoding?
# File 'ext/stringio/stringio.c', line 2065
static VALUE
strio_external_encoding(VALUE self)
{
struct StringIO *ptr = StringIO(self);
return rb_enc_from_encoding(get_enc(ptr));
}
#fcntl
[ GitHub ]#fileno
[ GitHub ]#flush
[ GitHub ]#fsync
[ GitHub ]
#getbyte ⇒ Integer?
Reads and returns the next integer byte (not character) from the stream:
s = 'foo'
s.bytes # => [102, 111, 111]
strio = StringIO.new(s)
strio.getbyte # => 102
strio.getbyte # => 111
strio.getbyte # => 111
Returns nil if at end-of-stream:
strio.eof? # => true
strio.getbyte # => nil
Returns a byte, not a character:
s = 'тест'
s.bytes # => [209, 130, 208, 181, 209, 129, 209, 130]
strio = StringIO.new(s)
strio.getbyte # => 209
strio.getbyte # => 130
s = 'こんにちは'
s.bytes # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175]
strio = StringIO.new(s)
strio.getbyte # => 227
strio.getbyte # => 129
Related: #getc.
# File 'ext/stringio/stringio.c', line 998
static VALUE
strio_getbyte(VALUE self)
{
struct StringIO *ptr = readable(self);
int c;
if (eos_p(ptr)) {
return Qnil;
}
c = RSTRING_PTR(ptr->string)[ptr->pos++];
return CHR2FIX(c);
}
#getc ⇒ character, ...
Reads and returns the next character (or byte; see below) from the stream:
strio = StringIO.new('foo')
strio.getc # => "f"
strio.getc # => "o"
strio.getc # => "o"
Returns nil if at end-of-stream:
strio.eof? # => true
strio.getc # => nil
Returns characters, not bytes:
strio = StringIO.new('тест')
strio.getc # => "т"
strio.getc # => "е"
strio = StringIO.new('こんにちは')
strio.getc # => "こ"
strio.getc # => "ん"
In each of the examples above, the stream is positioned at the beginning of a character; in other cases that need not be true:
strio = StringIO.new('こんにちは') # Five 3-byte characters.
strio.pos = 3 # => 3 # At beginning of second character; returns character.
strio.getc # => "ん"
strio.pos = 4 # => 4 # At second byte of second character; returns byte.
strio.getc # => "\x82"
strio.pos = 5 # => 5 # At third byte of second character; returns byte.
strio.getc # => "\x93"
Related: #getbyte.
# File 'ext/stringio/stringio.c', line 972
static VALUE
strio_getc(VALUE self)
{
struct StringIO *ptr = readable(self);
rb_encoding *enc = get_enc(ptr);
VALUE str = ptr->string;
long pos = ptr->pos;
int len;
char *p;
if (eos_p(ptr)) {
return Qnil;
}
p = RSTRING_PTR(str)+pos;
len = rb_enc_mbclen(p, RSTRING_END(str), enc);
ptr->pos += len;
return enc_subseq(str, pos, len, enc);
}
#gets(sep = $/, chomp: false) ⇒ String?
#gets(limit, chomp: false) ⇒ String?
#gets(sep, limit, chomp: false) ⇒ String?
String?
#gets(limit, chomp: false) ⇒ String?
#gets(sep, limit, chomp: false) ⇒ String?
Reads and returns a line from the stream; returns nil if at end-of-stream.
Side effects:
-
Increments stream position by the number of bytes read.
-
Assigns the return value to global variable
$_.
With no arguments given, reads a line using the default record separator (global variable $/,* whose initial value is "\n"):
strio = StringIO.new(TEXT)
strio.pos # => 0
strio.gets # => "First line\n"
strio.pos # => 11
$_ # => "First line\n"
strio.gets # => "Second line\n"
strio.read # => "\nFourth line\nFifth line\n"
strio.eof? # => true
strio.gets # => nil
strio = StringIO.new('тест') # Four 2-byte characters.
strio.pos # => 0
strio.gets # => "тест"
strio.pos # => 8
Argument sep
With only string argument sep given, reads a line using that string as the record separator:
strio = StringIO.new(TEXT)
strio.gets(' ') # => "First "
strio.gets(' ') # => "line\nSecond "
strio.gets(' ') # => "line\n\nFourth "
Argument limit
With only integer argument limit given, reads a line using the default record separator; limits the size (in characters) of each line to the given limit:
strio = StringIO.new(TEXT)
strio.gets(10) # => "First line"
strio.gets(10) # => "\n"
strio.gets(10) # => "Second lin"
strio.gets(10) # => "e\n"
Arguments sep and limit
With arguments sep and limit both given, honors both:
strio = StringIO.new(TEXT)
strio.gets(' ', 10) # => "First "
strio.gets(' ', 10) # => "line\nSecon"
strio.gets(' ', 10) # => "d "
Position
As stated above, method gets reads and returns the next 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:
strio = StringIO.new(TEXT)
strio.pos = 12
strio.gets # => "econd line\n"
The position need not be at a character boundary:
strio = StringIO.new('тест') # Four 2-byte characters.
strio.pos = 2 # At beginning of second character.
strio.gets # => "ест"
strio.pos = 3 # In middle of second character.
strio.gets # => "\xB5ст"
Special Record Separators
Like some methods in class ::IO, method gets honors two special record separators; see Special Line Separators:
strio = StringIO.new(TEXT)
strio.gets('') # Read "paragraph" (up to empty line).
# => "First line\nSecond line\n\n"
strio = StringIO.new(TEXT)
strio.gets(nil) # "Slurp": read all.
# => "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 the trailing newline (if any) from the returned line:
strio = StringIO.new(TEXT)
strio.gets # => "First line\n"
strio.gets(chomp: true) # => "Second line"
Related: #each_line.
# File 'ext/stringio/stringio.c', line 1434
static VALUE
strio_gets(int argc, VALUE *argv, VALUE self)
{
struct StringIO *ptr = readable(self);
struct getline_arg arg;
VALUE str;
if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
if (NIL_P(ptr->string)) return Qnil;
return rb_enc_str_new(0, 0, get_enc(ptr));
}
str = strio_getline(&arg, ptr);
rb_lastline_set(str);
return str;
}
#initialize_copy(orig)
# File 'ext/stringio/stringio.c', line 723
static VALUE
strio_copy(VALUE copy, VALUE orig)
{
struct StringIO *ptr, *old_ptr;
VALUE old_string = Qundef;
orig = rb_convert_type(orig, T_DATA, "StringIO", "to_strio");
if (copy == orig) return copy;
ptr = StringIO(orig);
old_ptr = check_strio(copy);
if (old_ptr) {
old_string = old_ptr->string;
strio_free(old_ptr);
}
DATA_PTR(copy) = ptr;
RB_OBJ_WRITTEN(copy, old_string, ptr->string);
RBASIC(copy)->flags &= ~STRIO_READWRITE;
RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
++ptr->count;
return copy;
}
#internal_encoding ⇒ nil
Returns nil; for compatibility with ::IO.
# File 'ext/stringio/stringio.c', line 2079
static VALUE
strio_internal_encoding(VALUE self)
{
return Qnil;
}
#isatty
[ GitHub ]
#length ⇒ Integer
#size ⇒ Integer
Also known as: #size
Integer
#size ⇒ Integer
Returns the size of the buffer string.
# File 'ext/stringio/stringio.c', line 2013
static VALUE
strio_size(VALUE self)
{
VALUE string = StringIO(self)->string;
if (NIL_P(string)) {
return INT2FIX(0);
}
return ULONG2NUM(RSTRING_LEN(string));
}
#pid
[ GitHub ]
#pread(maxlen, offset) ⇒ String
#pread(maxlen, offset, out_string) ⇒ String
String
#pread(maxlen, offset, out_string) ⇒ String
See IO#pread.
# File 'ext/stringio/stringio.c', line 1893
static VALUE
strio_pread(int argc, VALUE *argv, VALUE self)
{
VALUE rb_len, rb_offset, rb_buf;
rb_scan_args(argc, argv, "21", &rb_len, &rb_offset, &rb_buf);
long len = NUM2LONG(rb_len);
long offset = NUM2LONG(rb_offset);
if (len < 0) {
rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len);
}
if (len == 0) {
if (NIL_P(rb_buf)) {
return rb_str_new("", 0);
}
return rb_buf;
}
if (offset < 0) {
rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset));
}
struct StringIO *ptr = readable(self);
if (outside_p(ptr, offset)) {
rb_eof_error();
}
if (NIL_P(rb_buf)) {
return strio_substr(ptr, offset, len, rb_ascii8bit_encoding());
}
long rest = RSTRING_LEN(ptr->string) - offset;
if (len > rest) len = rest;
rb_str_resize(rb_buf, len);
rb_enc_associate(rb_buf, rb_ascii8bit_encoding());
MEMCPY(RSTRING_PTR(rb_buf), RSTRING_PTR(ptr->string) + offset, char, len);
return rb_buf;
}
#putc(obj) ⇒ Object
See IO#putc.
# File 'ext/stringio/stringio.c', line 1784
static VALUE
strio_putc(VALUE self, VALUE ch)
{
struct StringIO *ptr = writable(self);
VALUE str;
check_modifiable(ptr);
if (RB_TYPE_P(ch, T_STRING)) {
if (NIL_P(ptr->string)) return ch;
str = rb_str_substr(ch, 0, 1);
}
else {
char c = NUM2CHR(ch);
if (NIL_P(ptr->string)) return ch;
str = rb_str_new(&c, 1);
}
strio_write(self, str);
return ch;
}
#read([length [, outbuf]]) ⇒ String, ...
See IO#read.
# File 'ext/stringio/stringio.c', line 1818
static VALUE
strio_read(int argc, VALUE *argv, VALUE self)
{
struct StringIO *ptr = readable(self);
VALUE str = Qnil;
long len;
int binary = 0;
switch (argc) {
case 2:
str = argv[1];
if (!NIL_P(str)) {
StringValue(str);
rb_str_modify(str);
}
/* fall through */
case 1:
if (!NIL_P(argv[0])) {
len = NUM2LONG(argv[0]);
if (len < 0) {
rb_raise(rb_eArgError, "negative length %ld given", len);
}
if (eos_p(ptr)) {
if (!NIL_P(str)) rb_str_resize(str, 0);
return len > 0 ? Qnil : rb_str_new(0, 0);
}
binary = 1;
break;
}
/* fall through */
case 0:
if (NIL_P(ptr->string)) return Qnil;
len = RSTRING_LEN(ptr->string);
if (len <= ptr->pos) {
rb_encoding *enc = get_enc(ptr);
if (NIL_P(str)) {
str = rb_str_new(0, 0);
}
else {
rb_str_resize(str, 0);
}
rb_enc_associate(str, enc);
return str;
}
else {
len -= ptr->pos;
}
break;
default:
rb_error_arity(argc, 0, 2);
}
if (NIL_P(str)) {
rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
str = strio_substr(ptr, ptr->pos, len, enc);
}
else {
long rest = RSTRING_LEN(ptr->string) - ptr->pos;
if (len > rest) len = rest;
rb_str_resize(str, len);
MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len);
if (!binary) {
rb_enc_copy(str, ptr->string);
}
}
ptr->pos += RSTRING_LEN(str);
return str;
}
#readlines(sep = $/, chomp: false) ⇒ Array
#readlines(limit, chomp: false) ⇒ Array
#readlines(sep, limit, chomp: false) ⇒ Array
Array
#readlines(limit, chomp: false) ⇒ Array
#readlines(sep, limit, chomp: false) ⇒ Array
See IO#readlines.
# File 'ext/stringio/stringio.c', line 1668
static VALUE
strio_readlines(int argc, VALUE *argv, VALUE self)
{
VALUE ary, line;
struct StringIO *ptr = readable(self);
struct getline_arg arg;
if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) {
rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
}
ary = rb_ary_new();
while (!NIL_P(line = strio_getline(&arg, ptr))) {
rb_ary_push(ary, line);
}
return ary;
}
#reopen(other, mode = 'r+') ⇒ self
# File 'ext/stringio/stringio.c', line 823
static VALUE
strio_reopen(int argc, VALUE *argv, VALUE self)
{
rb_io_taint_check(self);
if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) {
return strio_copy(self, *argv);
}
return strio_init(argc, argv, StringIO(self), self);
}
#rewind ⇒ 0
Sets the current position and line number to zero; see Position and Line Number.
# File 'ext/stringio/stringio.c', line 873
static VALUE
strio_rewind(VALUE self)
{
struct StringIO *ptr = StringIO(self);
ptr->pos = 0;
ptr->lineno = 0;
return INT2FIX(0);
}
#seek(offset, whence = SEEK_SET) ⇒ 0
Sets the current position to the given integer offset (in bytes), with respect to a given constant whence; see Position.
# File 'ext/stringio/stringio.c', line 890
static VALUE
strio_seek(int argc, VALUE *argv, VALUE self)
{
VALUE whence;
struct StringIO *ptr = StringIO(self);
long amount, offset;
rb_scan_args(argc, argv, "11", NULL, &whence);
amount = NUM2LONG(argv[0]);
if (CLOSED(self)) {
rb_raise(rb_eIOError, "closed stream");
}
switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
case 0:
offset = 0;
break;
case 1:
offset = ptr->pos;
break;
case 2:
if (NIL_P(ptr->string)) {
offset = 0;
} else {
offset = RSTRING_LEN(ptr->string);
}
break;
default:
error_inval("invalid whence");
}
if (amount > LONG_MAX - offset || amount + offset < 0) {
error_inval(0);
}
ptr->pos = amount + offset;
return INT2FIX(0);
}
#set_encoding(ext_enc, [int_enc[, opt]]) ⇒ strio
Specify the encoding of the StringIO as ext_enc. Use the default external encoding if ext_enc is nil. 2nd argument int_enc and optional hash opt argument are ignored; they are for API compatibility to ::IO.
# File 'ext/stringio/stringio.c', line 2095
static VALUE
strio_set_encoding(int argc, VALUE *argv, VALUE self)
{
rb_encoding* enc;
struct StringIO *ptr = StringIO(self);
VALUE ext_enc, int_enc, opt;
argc = rb_scan_args(argc, argv, "11:", &ext_enc, &int_enc, &opt);
if (NIL_P(ext_enc)) {
enc = rb_default_external_encoding();
}
else {
enc = rb_find_encoding(ext_enc);
if (!enc) {
rb_io_enc_t convconfig;
int oflags;
rb_io_mode_t fmode;
VALUE vmode = rb_str_append(rb_str_new_cstr("r:"), ext_enc);
rb_io_extract_modeenc(&vmode, 0, Qnil, &oflags, &fmode, &convconfig);
enc = convconfig.enc2;
}
}
ptr->enc = enc;
if (!NIL_P(ptr->string) && WRITABLE(self) && !str_chilled_p(ptr->string)) {
rb_enc_associate(ptr->string, enc);
}
return self;
}
#set_encoding_by_bom ⇒ strio?
Sets the encoding according to the BOM (Byte Order Mark) in the string.
Returns self if the BOM is found, otherwise +nil.
# File 'ext/stringio/stringio.c', line 2135
static VALUE
strio_set_encoding_by_bom(VALUE self)
{
struct StringIO *ptr = StringIO(self);
if (!set_encoding_by_bom(ptr)) return Qnil;
return rb_enc_from_encoding(ptr->enc);
}
#length ⇒ Integer
#size ⇒ Integer
Integer
#size ⇒ Integer
Alias for #length.
#sync ⇒ true
Returns true; implemented only for compatibility with other stream classes.
# File 'ext/stringio/stringio.c', line 932
static VALUE
strio_get_sync(VALUE self)
{
StringIO(self);
return Qtrue;
}
#sync=
[ GitHub ]#tell
[ GitHub ]
#truncate(integer) ⇒ 0
Truncates the buffer string to at most integer bytes. The stream must be opened for writing.
# File 'ext/stringio/stringio.c', line 2030
static VALUE
strio_truncate(VALUE self, VALUE len)
{
VALUE string = writable(self)->string;
long l = NUM2LONG(len);
long plen;
if (l < 0) {
error_inval("negative length");
}
if (NIL_P(string)) return 0;
plen = RSTRING_LEN(string);
rb_str_resize(string, l);
if (plen < l) {
MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
}
return INT2FIX(0);
}
#ungetbyte(byte) ⇒ nil
Pushes back (“unshifts”) an 8-bit byte onto the stream; see Byte IO.
# File 'ext/stringio/stringio.c', line 1088
static VALUE
strio_ungetbyte(VALUE self, VALUE c)
{
struct StringIO *ptr = readable(self);
check_modifiable(ptr);
if (NIL_P(ptr->string)) return Qnil;
if (NIL_P(c)) return Qnil;
if (RB_INTEGER_TYPE_P(c)) {
/* rb_int_and() not visible from exts */
VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
const char cc = NUM2INT(v) & 0xFF;
strio_unget_bytes(ptr, &cc, 1);
}
else {
StringValue(c);
strio_unget_string(ptr, c);
}
return Qnil;
}
#ungetc(character) ⇒ nil
Pushes back (“unshifts”) a character or integer onto the stream; see Character IO.
# File 'ext/stringio/stringio.c', line 1046
static VALUE
strio_ungetc(VALUE self, VALUE c)
{
struct StringIO *ptr = readable(self);
rb_encoding *enc, *enc2;
check_modifiable(ptr);
if (NIL_P(ptr->string)) return Qnil;
if (NIL_P(c)) return Qnil;
if (RB_INTEGER_TYPE_P(c)) {
int len, cc = NUM2INT(c);
char buf[16];
enc = rb_enc_get(ptr->string);
len = rb_enc_codelen(cc, enc);
if (len <= 0) {
rb_enc_uint_chr(cc, enc); /* to raise an exception */
UNREACHABLE;
}
rb_enc_mbcput(cc, buf, enc);
return strio_unget_bytes(ptr, buf, len);
}
else {
StringValue(c);
if (RSTRING_LEN(c) == 0) return Qnil;
enc = rb_enc_get(ptr->string);
enc2 = rb_enc_get(c);
if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
c = rb_str_conv_enc(c, enc2, enc);
}
strio_unget_string(ptr, c);
return Qnil;
}
}
#write(string, ...) ⇒ Integer
#syswrite(string) ⇒ Integer
Integer
#syswrite(string) ⇒ Integer
Appends the given string to the underlying buffer string. The stream must be opened for writing. If the argument is not a string, it will be converted to a string using to_s. Returns the number of bytes written. See IO#write.
# File 'ext/stringio/stringio.c', line 1696
static VALUE
strio_write_m(int argc, VALUE *argv, VALUE self)
{
long len = 0;
while (argc-- > 0) {
/* StringIO can't exceed long limit */
len += strio_write(self, *argv++);
}
return LONG2NUM(len);
}