Skip to content

Instantly share code, notes, and snippets.

@jmhakvoort
Last active February 9, 2026 13:54
Show Gist options
  • Select an option

  • Save jmhakvoort/d1556438177a213ddafeff542ca3b1a6 to your computer and use it in GitHub Desktop.

Select an option

Save jmhakvoort/d1556438177a213ddafeff542ca3b1a6 to your computer and use it in GitHub Desktop.
Cool Enumerable#each_with_progress I once wrote so I can see how long iterating will take. I have waited too long on empty processes already. Most of the code is a blatant copy of existing code I found on the interwebs, but unfortunately I don't remember where. My contributions are mostly with the RAILS_ENV guard and the output.
module Enumerable
def each_with_progress(&block)
if ENV['RAILS_ENV'] == 'test'
each do |element|
block.call element
end
else
out = $stderr
time = Time.current
total = count
pretext = "> starting @ #{time.strftime('%H:%M')} -- processing #{total} items..."
each_with_index do |element, i|
out.print enumerating_line(i + 1, total, time)
block.call element
end
end_time = Time.current
duration = ((end_time - time) / 60).round(1)
duration_unit = duration > 1 ? "minutes" : "seconds"
out.print "\r< started @ #{time.strftime('%H:%M')} -- processed #{total} items in #{duration} #{duration_unit}\n"
end
self
end
protected
def enumerating_progress_spinner
@enumerating_progress_spinner ||= Enumerator.new do |e|
loop do
e.yield '|'
e.yield '/'
e.yield '-'
e.yield '\\'
end
end
end
def enumerating_line(increment, total, time)
percentage = (increment * 100.0) / total
difference = (total * (Time.current - time)) / increment
pretext = ["\r> started @ ", time.strftime("%H:%M"), " -- processing #{total} items ", '[ETA: ', (time + difference).strftime("%H:%M"), '] '].join
posttext = format("[%5.1f%%]", percentage)
progress = ((percentage / 100.0) * (Integer((`tput cols` || '80').chomp) - pretext.length - posttext.length - 2)).ceil.times.map {}.join('=')
spinner = percentage >= 100 ? " " : enumerating_progress_spinner.next
[pretext, progress, spinner, posttext].join(" ")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment