# Unpack block?

**URL:** <https://www.ruby-forum.com/t/unpack-block/72075>\
**Category:** Ruby\
**Created:** [October 14, 2006, 1:14am UTC](https://www.ruby-forum.com/t/unpack-block/72075 "2006-10-14T01:14:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [October 14, 2006, 1:14am UTC](https://www.ruby-forum.com/t/unpack-block/72075/1 "2006-10-14T01:14:25Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [October 14, 2006, 1:46am UTC](https://www.ruby-forum.com/t/unpack-block/72075/2 "2006-10-14T01:46:40Z")

</div>

On 10/13/06, Tim B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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. 😉

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [October 14, 2006, 1:52am UTC](https://www.ruby-forum.com/t/unpack-block/72075/3 "2006-10-14T01:52:44Z")

</div>

On 10/13/06, Brian M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On 10/13/06, Tim B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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)

On second thought… each\_unapck is a much better name.

Brian.

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [October 14, 2006, 2:04am UTC](https://www.ruby-forum.com/t/unpack-block/72075/4 "2006-10-14T02:04:46Z")

</div>

On 10/13/06, Brian M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On second thought… each\_unapck is a much better name.

Shouldn’t it just be ‘unpack’, and have some ‘if block\_given?’ juice  
squeezed on it?

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [October 14, 2006, 5:55pm UTC](https://www.ruby-forum.com/t/unpack-block/72075/5 "2006-10-14T17:55:49Z")

</div>

Hi,

In message “Re: unpack block?”  
on Sat, 14 Oct 2006 08:14:14 +0900, Tim B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|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

No, it’s a quite interesting idea. I implemented it with a few  
minutes hack. I will check it in later and try to see how it works  
(in HEAD, of course).

```
						matz.

```

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [October 14, 2006, 5:35pm UTC](https://www.ruby-forum.com/t/unpack-block/72075/6 "2006-10-14T17:35:45Z")

</div>

On 10/13/06, Wilson B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > def unpack\_each(format)
> > 
> > On second thought… each\_unapck is a much better name.
> 
> Shouldn’t it just be ‘unpack’, and have some ‘if block\_given?’ juice  
> squeezed on it?

Not when I am monkey patching [1] like this. If I felt like writing a  
worthwhile implementation… then that might happen. I am an advocate  
of intelligent interfaces but I am also an advocate of avoiding too  
many invasive changes when they really aren’t needed. It is perfectly  
sensible to play around with this using a name each\_unpack.

And it is a sort of iteration… like each\_line and each\_byte, we get  
repeated results from a sort of scan like transformation process. Each  
series of unpacked array… I think it fits.

Anyway… I sound like a broken record. Just woke up from the aftermath  
of an 8 hour long party at my apartment here in NYC. 😉

Brian.

[1] I have no problem reopening classes but when I override something  
I always take great care to minimize change. If this is so great, we  
could merge the idea into ruby’s code base and call it standard.
