# Rolling String Buffer needed

**URL:** <https://www.ruby-forum.com/t/rolling-string-buffer-needed/176585>\
**Category:** Ruby\
**Created:** [October 2, 2009, 6:55pm UTC](https://www.ruby-forum.com/t/rolling-string-buffer-needed/176585 "2009-10-02T18:55:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [October 2, 2009, 6:55pm UTC](https://www.ruby-forum.com/t/rolling-string-buffer-needed/176585/1 "2009-10-02T18:55:42Z")

</div>

I have constant ascii data streaming in, each message terminated with  
\n, currently I look for something specific and throw away the other  
stuff and then look for something specific and throw away the other  
stuff…etc

What I need now is a way to keep everything received exactly as is, in a  
rolling string buffer. So say the last 100 messages (a message to me is  
a whole string terminated with \n) which could be available at any time  
in a string variable, maybe called: last\_100\_messages

And when I append another variable length message/line to this string  
buffer that ends with a \n, I want the oldest message to go  
away(specifically go into a text file), so ALL messages are available in  
a text file for later.

Problem is the append \<\< method, puts the new lines on the end of the  
string, I want the end of the string to always be the oldest message  
that is about to be placed into a txt file that has all messages at some  
point.

So in short, a rolling buffer that holds a specific amount of \n  
terminated messages(100 strings terminated with \n’s), not a specific  
amount of data/bytes. Where the front of the string holds the most  
recent addition to the rolling buffer, and where the end of the string  
holds the message that is about to be added to a file.

Also if easier, an array where each element is one message would work as  
well, where array[0] is the most recent message.

I have been looking at strio, but not sure how to use it in this manner.

Thanks a lot for your input,  
Matt

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [October 2, 2009, 7:23pm UTC](https://www.ruby-forum.com/t/rolling-string-buffer-needed/176585/2 "2009-10-02T19:23:28Z")

</div>

On Oct 2, 2009, at 9:55 AM, Matt B. wrote:

> time
> 
> holds the message that is about to be added to a file.
> 
> Also if easier, an array where each element is one message would  
> work as  
> well, where array[0] is the most recent message.
> 
> I have been looking at strio, but not sure how to use it in this  
> manner.

I think you could just write a class that wraps up a list. Something  
like this:

class MyBuff  
def initialize max\_size, filename  
@max\_size = max\_size  
@list = []  
@file = File.open(filename, ‘wb’)  
end

def push string  
@list.push string  
while @list.length \> @max\_size  
@file.write @list.pop  
end  
end

def [] i  
@list[i]  
end  
end

* * *

Aaron P.  
[http://tenderlovemaking.com](http://tenderlovemaking.com)

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [October 2, 2009, 7:31pm UTC](https://www.ruby-forum.com/t/rolling-string-buffer-needed/176585/3 "2009-10-02T19:31:26Z")

</div>

Aaron P. wrote:

> class MyBuff  
> def initialize max\_size, filename  
> @max\_size = max\_size  
> @list = []  
> @file = File.open(filename, ‘wb’)  
> end
> 
> def push string  
> @list.push string  
> while @list.length \> @max\_size  
> @file.write @list.pop  
> end  
> end
> 
> def [] i  
> @list[i]  
> end  
> end
> 
> * * *
> 
> Aaron P.  
> [http://tenderlovemaking.com](http://tenderlovemaking.com)

That looks great! So when I do pop on an array it does the highest  
index element? And when you push onto an array it puts it in index 0 ?

Thanks!  
Matt

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [October 2, 2009, 8:48pm UTC](https://www.ruby-forum.com/t/rolling-string-buffer-needed/176585/4 "2009-10-02T20:48:53Z")

</div>

Justin C. wrote:

> If you want it to act like a queue with the last element being the head,  
> then use pop/unshift.
> 
> irb(main):001:0\> a = [1,2,3,4]  
> =\> [1, 2, 3, 4]  
> irb(main):002:0\> a.pop  
> =\> 4  
> irb(main):003:0\> a.unshift 5  
> =\> [5, 1, 2, 3]  
> irb(main):004:0\> a.pop  
> =\> 3  
> irb(main):005:0\> a  
> =\> [5, 1, 2]
> 
> -Justin

Awesome, I think I need the last approach. So incorporating it into the  
class, I have…

class MyBuff  
def initialize max\_size, filename  
@max\_size = max\_size  
@list = []  
@file = File.open(filename, ‘wb’)  
end

```
def add_to_front string
  @list.unshift string #changed to unshift
  while @list.length > @max_size
    @file.write @list.pop
  end
end

def [] i
  @list[i]
end

```

end

Thanks to all, I think this will work great!  
-Matt

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [October 2, 2009, 8:36pm UTC](https://www.ruby-forum.com/t/rolling-string-buffer-needed/176585/5 "2009-10-02T20:36:04Z")

</div>

Matt B. wrote:

> > ```
> > @list.push string
> > 
> > ```
> > 
> > * * *

Actually, push/pop works like it’s a stack, with the top being the last  
element. So pop removes and returns the last element, while push appends  
to the end.

irb(main):001:0\> a = [1,2,3,4]  
=\> [1, 2, 3, 4]  
irb(main):002:0\> a.pop  
=\> 4  
irb(main):003:0\> a.push 5  
=\> [1, 2, 3, 5]  
irb(main):004:0\> a.pop  
=\> 5  
irb(main):005:0\> a  
=\> [1, 2, 3]

If you want it to act like a queue with the first element being the  
head, then use shift/push.

rb(main):001:0\> a = [1,2,3,4]  
=\> [1, 2, 3, 4]  
irb(main):002:0\> a.shift  
=\> 1  
irb(main):003:0\> a.push 5  
=\> [2, 3, 4, 5]  
irb(main):004:0\> a.shift  
=\> 2  
irb(main):005:0\> a  
=\> [3, 4, 5]

If you want it to act like a queue with the last element being the head,  
then use pop/unshift.

irb(main):001:0\> a = [1,2,3,4]  
=\> [1, 2, 3, 4]  
irb(main):002:0\> a.pop  
=\> 4  
irb(main):003:0\> a.unshift 5  
=\> [5, 1, 2, 3]  
irb(main):004:0\> a.pop  
=\> 3  
irb(main):005:0\> a  
=\> [5, 1, 2]

-Justin

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [October 3, 2009, 5:35am UTC](https://www.ruby-forum.com/t/rolling-string-buffer-needed/176585/6 "2009-10-03T05:35:10Z")

</div>

VTD-XML 2.7 is released and can be downloaded at

> **[VTD-XML: The Future of XML Processing - Browse Files at SourceForge.net](https://sourceforge.net/projects/vtd-xml/files/)**
>
> VTD-XML is the next generation XML parser/indexer/editor/slicer/assembler/xpath-engine that goes beyond DOM, SAX and PULL in performance, memory…

Below is a summary of what are the new features and enhancements.

Expanded VTD-XML’s Core API

- VTDNav: toStringUpperCase, toStringLowerCase, contains(), endsWith(),  
startsWith()
- Extended VTD added in-memory buffer support

Improved Xpath

- added the following XPath 2.0 functions: abs(), ends-with(),  
upper-case(),  
lower-case()
- added support for variable reference
- significantly enhanced XPath syntax, checking error reporting (Special  
thanks to Mark Swanson)
- Internal performance tuning

Bug fixes and Code Enhancement

- C version significantly removed warning message, fix memory leak  
during  
Xpath expression parsing,
- Various bug fies (Special thanks to Jon Roberts, John Zhu, Matej  
Spiller,  
Steve Polson, and Romain La Tellier)
