Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
IO::Buffer.for
VALUE
rb_io_buffer_type_for(VALUE klass, VALUE string)
{
klass = io_buffer_storage_class(klass);
StringValue(string);
// If the string is frozen, both code paths are okay.
// If the string is not frozen, if a block is not given, it must be frozen.
if (rb_block_given_p()) {
struct io_buffer_for_yield_instance_arguments arguments = {
.klass = klass,
.string = string,
.instance = Qnil,
.flags = 0,
};
return rb_ensure(io_buffer_for_yield_instance, (VALUE)&arguments, io_buffer_for_yield_instance_ensure, (VALUE)&arguments);
}
else {
// Use a Ruby-visible frozen snapshot as the backing source. A hidden
// temporary frozen String cannot be returned by IO::Buffer#source.
string = rb_str_new_frozen(string);
return io_buffer_for_make_instance(klass, string, RB_IO_BUFFER_READONLY);
}
}
Creates a zero-copy IO::Buffer from the given string’s memory. Without a block, a frozen snapshot of the string is used as the buffer source, so later changes to the original string do not affect the buffer. When a block is provided, the buffer is associated directly with the string’s internal buffer and updating the buffer will update the string.
In the block form, the string is locked and cannot be modified while the block is executing.
If the string is frozen, it will create a read-only buffer which cannot be modified. If the string is shared, it may trigger a copy-on-write when using the block form.
string = 'test' buffer = IO::Buffer.for(string) buffer.external? #=> true buffer.get_string(0, 1) # => "t" string # => "test" buffer.resize(100) # in `resize': Cannot resize external buffer! (IO::Buffer::AccessError) IO::Buffer.for(string) do |buffer| buffer.set_string("T") string # => "Test" end