On 10/13/06, Tim Bray <tbray / textuality.com> wrote:
> unpack doesn't seem to take a block.  This seems like an obvious
> thing to want if I'm going to work with a big input string and not
> burn memory.  Am I missing something? -Tim

Possibly a good idea. Lets go ahead and try it out.

class String
  def unpack_each(format)
    index = 0
    loop {
      break if index >= self.size - 1
      yield ary = self[index..-1].unpack(format)
      # We can't pack nils nor can we compact and pack too little data.
      break if ary.include? nil
      index += ary.pack(format).size
    }
  end
end

So it's not the greatest code ever but it seems to work [1]:

input = ([42] * 99).pack('c*')
count = 0
last = nil
input.unpack_each('cc') {|a| last = a; count += 1}
p count #=> 50
p last #=> [42, nil] Ok. boundaries should work like normal pack.

Of course, it might also be a good idea to consider reading
conservative chunks from whatever you are unpacking and iterating over
those while unpacking but having both ways available might be nice.

Brian.

[1] The usual disclaimers apply. I have not build a good test suite
for this because I only plan on using it as a proof of concept in this
email. I recommend doing so if any of the code is used. ;-)