-
-
Notifications
You must be signed in to change notification settings - Fork 131
Custom Output Classes
WARNING: THIS FEATURE WORKS BUT BREAKING CHANGES WILL NOT BE CONSIDERED CAUSE FOR A MAJOR VERSION SEMVER BUMP. USE AT YOUR OWN RISK!
By default ruby-progressbar
will attempt to cover the main use cases for outputting the bar. These include outputting to a screen and outputting to a file-ish sort of thing. The technical term would be TTY and non-TTY. However there are some edge cases whereby you might want something different to happen than either of those.
For example, you might want to log the progressbar to a file with some special logic, or you may want to log to a file in certain cases and to a screen in other cases, or you may want to log to a screen and a file at the same time.
Whatever the case, you now have effectively full control over how the progressbar is sent to a destination.
One of the use cases for a custom outputter is a "null" destination. In a case like this, the user doesn't ever want to see the progressbar and instead only ever wants to access it via #to_s
. A use case might be a CLI program which, when executed, prints the current status of multiple bars (maybe with extra information before or after it) and then exits. Since by default progressbar prints itself to stdout
on every update, there would be undesirable output for the above case.
Side Note: There is a builtin output class for just this use case which is officially supported. See the wiki article for details.
In order to fix this issue, we can create a custom Output
class which is a no-op for all of our base Output
class' methods. Here's what that might look like:
require 'ruby-progressbar/output'
class MyNullOutput < ProgressBar::Output
alias refresh_with_format_change with_refresh
def clear; end
def log(_string); end
def refresh(*); end
def clear_string
''
end
def bar_update_string
''
end
def default_format
''
end
def resolve_format(_format)
''
end
def eol
''
end
end
IMPORTANT NOTE: The class must inherit from ProgressBar::Output
, even if every method is overridden.
Now, in order to use it, all we have to do is pass it into the constructor of the progressbar when we create it.
progressbar = ProgressBar.create(output: MyNullOutput)
ruby-progressbar
will take care of the rest!
If you want to implement an Output
class which actually sends the progressbar somewhere, you'll need to override stream
and set it to return an IO
-like object.
class MyOutput < ProgressBar::Output
alias refresh_with_format_change with_refresh
# This is REQUIRED for the custom output class to work properly
def stream
$stdout
end
def clear
stream.print clear_string
stream.print "\r"
end
def log(message)
clear
stream.puts "This is a log statement \/ \/ \/"
stream.puts message
refresh(:force => true) unless bar.stopped?
end
def bar_update_string
bar.to_s + ' ' + Time.now.iso8601
end
def default_format
'This is some custom stuff %w%i'
end
def resolve_format(_format)
default_format
end
def eol
"\n"
end
end