Created
March 6, 2016 10:40
-
-
Save denpatin/d489fd206707dda0941b to your computer and use it in GitHub Desktop.
Showing progress bar for each-ish methods
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=begin | |
Usage examples: | |
big_array.each_with_progress(){ |e| ... } | |
(0...1000000).each_with_progress(){ |i| ... } | |
big_hash.each_key_with_progress(){ |k| ... } | |
IO.foreach_with_progress("big.txt"){ |line| ... } | |
open_with_progress("big.txt"){ |f| ... } | |
open("big.txt") do |f| | |
f.each_line_with_progress(){ |line| ... } | |
end | |
ARGF.each_line_with_progress(){ |line| ... } | |
=end | |
require "progressbar" | |
require "enumerator" | |
module Kernel | |
def open_with_progress(path, *args, &block) | |
File.open_with_progress(path, *args, &block) | |
end | |
end | |
class File | |
def self.open_with_progress(path, *args, &block) | |
open(path, *args) do |f| | |
f.with_progress() do | |
yield(f) | |
end | |
end | |
end | |
def with_progress(title = File.basename(self.path), &block) | |
pos = self.pos | |
seek(0, IO::SEEK_END) | |
size = self.pos | |
self.pos = pos | |
prog_bar = ProgressBar.new(title, size) | |
opened = true | |
thread = Thread.new() do | |
while opened | |
prog_bar.set(self.pos) rescue nil | |
sleep(0.1) | |
end | |
end | |
begin | |
yield() | |
ensure | |
opened = false | |
thread.join() | |
prog_bar.set(self.pos) rescue nil | |
prog_bar.halt() | |
end | |
end | |
end | |
class IO | |
def self.foreach_with_progress(path, &block) | |
File.open_with_progress(path) do |f| | |
f.each_line(&block) | |
end | |
end | |
end | |
class << ARGF | |
def with_progress(title = File.basename(self.path), &block) | |
if !self.file.is_a?(File) | |
yield() | |
else | |
paths = [self.file.path] + ARGV | |
file_poses = {} | |
total = 0 | |
for path in paths | |
file_poses[path] = total | |
total += File.size(path) | |
end | |
prog_bar = ProgressBar.new("", total) | |
opened = true | |
thread = Thread.new() do | |
while opened | |
prog_bar.format = | |
("%-14s" % File.basename(self.file.path)).gsub(/%/, "%%") + | |
" %3d%% %s %s" | |
prog_bar.format_arguments = [:percentage, :bar, :stat] | |
prog_bar.set(file_poses[self.file.path] + self.pos) rescue nil | |
sleep(0.1) | |
end | |
end | |
begin | |
yield() | |
ensure | |
opened = false | |
thread.join() | |
begin | |
pos = self.closed? ? total : file_poses[self.file.path] + self.pos | |
prog_bar.set(pos) | |
rescue | |
end | |
prog_bar.halt() | |
end | |
end | |
end | |
def each_line_with_progress(rs = $/, &block) | |
with_progress() do | |
each_line(rs, &block) | |
end | |
end | |
end | |
module Enumerable | |
def each_with_progress(title = "", size = self.size, &block) | |
prog_bar = ProgressBar.new(title, size) | |
begin | |
each() do |*args| | |
args.size==1 ? yield(args[0]) : yield(*args) | |
prog_bar.inc() | |
end | |
ensure | |
prog_bar.halt() | |
end | |
end | |
end | |
class Hash | |
def each_key_with_progress(title = "", &block) | |
enum_for(:each_key).each_with_progress(title, self.size, &block) | |
end | |
def each_value_with_progress(title = "", &block) | |
enum_for(:each_value).each_with_progress(title, self.size, &block) | |
end | |
def each_pair_with_progress(title = "", &block) | |
enum_for(:each_pair).each_with_progress(title, self.size, &block) | |
end | |
end | |
class Range | |
def each_with_progress(title = "", &block) | |
if !self.begin.is_a?(Integer) || !self.end.is_a?(Integer) | |
raise(ArgumentError, "Both of begin and end must be Integer") | |
end | |
super(title, self.end - self.begin + (self.exclude_end? ? 0 : 1)) | |
end | |
end | |
if $0 == __FILE__ | |
case ARGV.shift() | |
when "argv" | |
ARGF.each_line_with_progress() do |line| | |
sleep(0.1) | |
end | |
when "file" | |
File.foreach_with_progress(ARGV[0]) do |line| | |
sleep(0.01) | |
end | |
when "array" | |
(0...10).to_a().each_with_progress("Array") do |i| | |
sleep(0.1) | |
end | |
when "range" | |
(0...10).each_with_progress("Range") do |i| | |
sleep(0.1) | |
end | |
when "hash" | |
Hash[*(0...20).to_a()].each_key_with_progress("Hash") do |i| | |
sleep(0.1) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment