# Clean way of pausing a loop?

**URL:** <https://www.ruby-forum.com/t/clean-way-of-pausing-a-loop/152406>\
**Category:** Ruby\
**Created:** [November 3, 2008, 4:38pm UTC](https://www.ruby-forum.com/t/clean-way-of-pausing-a-loop/152406 "2008-11-03T16:38:28Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [November 3, 2008, 4:38pm UTC](https://www.ruby-forum.com/t/clean-way-of-pausing-a-loop/152406/1 "2008-11-03T16:38:28Z")

</div>

It’s Monday and it’s relatively early, so I apologize if this isn’t  
worded too well.

Is there a clean way of pausing a loop/printing status every N  
iterations? I often use ruby to examine log files in a one-off  
fashion, and when dealing with files of 4-10 million lines, this is  
the sort of thing that becomes important. Small files are, obviously,  
not as big of a deal.

I know I can simply do this, but it doesn’t seem clean:

counter=0  
n=100  
foo.each do  
|bar|  
counter+=1  
if (counter%n).zero?  
sleep 0.1  
end

Thanks,  
Kyle  
end

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [November 3, 2008, 5:12pm UTC](https://www.ruby-forum.com/t/clean-way-of-pausing-a-loop/152406/2 "2008-11-03T17:12:01Z")

</div>

Kyle S. wrote:

> counter=0  
> n=100  
> foo.each do  
> |bar|  
> counter+=1  
> if (counter%n).zero?  
> sleep 0.1  
> end  
> What’s wrong with it? I can only think that if foo allows  
> .each\_with\_index, you could avoid the counter initialization and  
> addition. Can’t think of anything else.

Cheers,  
Mohit.  
11/4/2008 | 12:09 AM.

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [November 3, 2008, 5:55pm UTC](https://www.ruby-forum.com/t/clean-way-of-pausing-a-loop/152406/3 "2008-11-03T17:55:42Z")

</div>

Kyle S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> ```
> Kyle
> 
> ```
> 
> end

Maybe something like this?

module Enumerable  
def paused\_each n, sec, pause\_after=true  
counter = 0  
self.each do |e|  
yield e if pause\_after  
if (counter += 1) \>= n  
counter = 0  
sleep sec  
end  
yield e unless pause\_after  
end  
end  
end

[1,2,3,4,5,6,7].paused\_each(2,2) { |e| puts e }  
puts  
[1,2,3,4,5,6,7].paused\_each(2,2,false) { |e| puts e }

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [November 3, 2008, 6:20pm UTC](https://www.ruby-forum.com/t/clean-way-of-pausing-a-loop/152406/4 "2008-11-03T18:20:27Z")

</div>

On 03.11.2008 16:35, Kyle S. wrote:

> It’s Monday and it’s relatively early, so I apologize if this isn’t  
> worded too well.
> 
> Is there a clean way of pausing a loop/printing status every N  
> iterations? I often use ruby to examine log files in a one-off  
> fashion, and when dealing with files of 4-10 million lines, this is  
> the sort of thing that becomes important. Small files are, obviously,  
> not as big of a deal.

You can use ARGF.lineno when reading from ARGF:

robert@fussel ~  
$ seq 1 20 | ruby -e ‘ARGF.each {|l| puts “.”; puts ARGF.lineno if  
ARGF.lineno % 10 == 0}’  
.  
.  
.  
.  
.  
.  
.  
.  
.  
.  
10  
.  
.  
.  
.  
.  
.  
.  
.  
.  
.  
20

You can use IO.lineno when reading from a stream

robert@fussel ~  
$ seq 1 20 | ruby -e ‘$stdin.each {|l| puts “.”; puts $stdin.lineno if  
$stdin.lineno % 10 == 0}’  
.  
.  
.  
.  
.  
.  
.  
.  
.  
.  
10  
.  
.  
.  
.  
.  
.  
.  
.  
.  
.  
20

Or you can use #each\_with\_index.

robert@fussel ~  
$ seq 1 20 | ruby -e ‘$stdin.each\_with\_index {|l,i| puts “.”; puts i if  
i % 10 == 0}’  
.  
0  
.  
.  
.  
.  
.  
.  
.  
.  
.  
.  
10  
.  
.  
.  
.  
.  
.  
.  
.  
.

Or you can use $.:

robert@fussel ~  
$ seq 1 20 | ruby -ne ‘puts “.”; puts $. if $. % 10 == 0’  
.  
.  
.  
.  
.  
.  
.  
.  
.  
.  
10  
.  
.  
.  
.  
.  
.  
.  
.  
.  
.  
20

I’m sure I forgot one or more variants. 🙂

Cheers

robert

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [November 3, 2008, 9:22pm UTC](https://www.ruby-forum.com/t/clean-way-of-pausing-a-loop/152406/5 "2008-11-03T21:22:31Z")

</div>

On 03.11.2008 21:07, Kyle S. wrote:

> Hum. Well those all work, but aren’t those basically similar to what  
> I’m already doing?

They at least do not do the counting manually. That’s probably more  
efficient also since counting is done in C code.

Btw, there is one more option: use each\_slice. 🙂

> I was hoping to somehow have a handler that would inject the logic  
> into an existing loop.

I believe we have seen such a solution in this thread already. Here’s  
another one

class EI  
include Enumerable

def initialize(enum, steps, &inter)  
@enum = enum  
@steps = steps  
@inter = inter  
end

def each  
@enum.each\_with\_index do |e,i|  
inter.call if i % steps == 0 && i != 0  
yield e  
end  
self  
end  
end

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![kyle\_s](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kyle\_s](https://www.ruby-forum.com/u/kyle_s)\
**Post date:** [November 3, 2008, 9:09pm UTC](https://www.ruby-forum.com/t/clean-way-of-pausing-a-loop/152406/6 "2008-11-03T21:09:38Z")

</div>

Hum. Well those all work, but aren’t those basically similar to what  
I’m already doing?  
I was hoping to somehow have a handler that would inject the logic  
into an existing loop.

Oh well.

Thanks,  
Kyle
