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

Like other IO-type objects in Ruby, when you write to an IO, the character pointer advances.

>> s = StringIO.new
=> #<StringIO:0x3659d4>
>> s << 'foo'
=> #<StringIO:0x3659d4>
>> s << 'bar'
=> #<StringIO:0x3659d4>
>> s.pos
=> 6
>> s.rewind
=> 0
>> s.read
=> "foobar"

I did some benchmarks and the fastest approach is using the String#<< method. Using StringIO is a little bit slower.

s = ""; Benchmark.measure{5000000.times{s << "some string"}}
=>   3.620000   0.100000   3.720000 (  3.970463)

>> s = StringIO.new; Benchmark.measure{5000000.times{s << "some string"}}
=>   4.730000   0.120000   4.850000 (  5.329215)

Concatenating strings using the String#+ method is the slowest approach by many orders of magnitude:

s = ""; Benchmark.measure{10000.times{s = s + "some string"}}
=>   0.700000   0.560000   1.260000 (  1.420272)

s = ""; Benchmark.measure{10000.times{s << "some string"}}
=>   0.000000   0.000000   0.000000 (  0.005639)

So I think the right answer is that the equivalent to Java's StringBuffer is simply using String#<< in Ruby.