Why Doesn't Ruby Have a Real Stringbuffer or Stringio

Why doesn't Ruby have a real StringBuffer or StringIO?

I looked at the ruby documentation for StringIO, and it looks like what you want is StringIO#string, not StringIO#to_s

Thus, change your code to:

s = StringIO.new
s << 'foo'
s << 'bar'
s.string

Ruby StringIO for concurrent reading and writing

You should consider using a Queue. If you do not need thread safety, then a simple array might be fine too.

Should I close StringIO instances explicitly?

Well, reads and writes go straight to the underlying string; there's no extra buffers to flush, and no OS-level resources to return.

The only reason you might want to close the StringIO is to make subsequent IOs fail or if you needed to make closed? return true, which could be useful if you gave that StringIO to some other component. On the other hand, if you're just going to discard the StringIO a moment later, it doesn't matter in the slightest; the garbage collector doesn't care if it's marked as open or closed.

What is ruby's StringIO class really?

no, StringIO is more similar to StringReader/StringWriter than StringBuffer.

In Java StringBuffer is the mutable version of String (since String is immutable).

StringReader/StringWriter are handy classes meant to be used when you want to fake file access . You can read/write in a String with the same stream-oriented interface of Reader/Writer: it is immensely useful in unit testing.

Why does Ruby have separate data types for Fixnums and Bignums, but not Strings and really long strings?

Very crudely, Fixnums represent numbers that the computer can store in a processor register and perform basic arithmetic on. Bignums are necessary because they represent numbers that by definition can not be stored in single registers, and therefore require "special" processing called arbitrary-precision arithmetic in order to perform arithmetic on them.

In computer science, arbitrary-precision arithmetic, also called
bignum arithmetic [...] indicates that calculations are performed on
numbers whose digits of precision are limited only by the available
memory of the host system. This contrasts with the faster
fixed-precision arithmetic found in most arithmetic logic unit (ALU)
hardware, which typically offers between 8 and 64 bits of precision.

With strings, there is no such distinction. An arbitrarily long string never has arithmetic performed on it at the processor instruction level, so there's no reason to distinguish between a "short" string and a "long" string.

In regards to memory:

(Small) numbers can be manipulated directly as actual binary CPU instructions because they fit entirely into a single CPU memory address (called a register.)

Neither (big) numbers nor strings can because they overflow a processor's "number of bits." (This is what's meant by a "64-bit processor": A single numeric value can be represented and manipulated up to 64-bits of precision.)

Strings are allocated in memory as a series of numbers that represent characters (with different numbers representing different characters depending on the chosen encoding, such as UTF-8 or ASCII) and they span across multiple memory locations. The strings are never fed through CPU as atomic units though, whereas Fixnums are.

Bignums likewise can't be handled in the ALU because each value (potentially) takes up more memory than what is available in a single CPU register, so a separate package that defines the necessary mathematical operations to break down very large numbers, perform arithmetic on the smaller parts using the ALU and composite the individual answers together has to be written separately.

What's the Ruby equivalent for Java's StringReader?


r = StringIO.new("my text")

And here's the documentation.

Why does OpenURI treat files under 10kb in size as StringIO?

When one does network programming, you allocate a buffer of a reasonably large size and send and read units of data which will fit in the buffer. However, when dealing with files (or sometimes things called BLOBs) you cannot assume that the data will fit into your buffer. So, you need special handling for these large streams of data.

(Sometimes the units of data which fit into the buffer are called packets. However, packets are really a layer 4 thing, like frames are at layer 2. Since this is happening a layer 7, they might better be called messages.)

For replies larger than 10K, the open-uri library is setting up the extra overhead to write to a stream objects. When under the StringMax size, it just includes the string in the message, since it knows it can fit in the buffer.

Why doesn't this simple Ruby program print what I expect it to?

You are probably at the end of the stream, where there are no more bytes left. After writing and before reading you should rewind the file (reopen or seek to position 0).

require 'tempfile'
t = Tempfile.new('test-data')
t.open
t.sync = true
t << "apples"
t.puts "bananas"
t.seek 0
puts "contents are [#{t.read}] (#{t.size} bytes)"
t.close


Related Topics



Leave a reply



Submit