NAME
Acme::Spinners - A fully extensible framework...for creating text spinners.
SYNOPSIS
use strict;
use warnings;
use Acme::Spinners;
use Acme::Spinners::Simple; # simple clockwise rotating blade
my $spinner = new Acme::Spinners ();
$spinner->spinner(new Acme::Spinners::Simple());
$spinner->start();
sleep 5;
$spinner->stop();
sleep 1;
DESCRIPTION
Ever make a CLI application and needed a way to provide the user that something was going on? Want to do it with style? Need an entire modularized infrastructure to do it?
Acme::Spinners is your friend.
This module allows you to select from a small array of pre-defined spinners for your enjoyment. Even better, it allows you to make your own spinners for your enjoyment.
METHODS
new()
new()
just makes a new object. Simple enough. Takes no arguments (feel free to supply garbage ones to frighten code readers (we recommend anal => 1, explosive => "true"
).
spinner($spinner)
spinner($spinner)
sets the spinner you want to use. Takes one argument, a new instance of the spinner you want to use.
start()
start()
startes the fun. When called, the spinner starts. Takes no arguments.
THIS FUNCTION RETURNS IMMEDIATELY! If you call start
immediately followed by stop
, you will be sorely disappointed. This method allows you to return, do you business, and stop the spinner when you're done.
stop()
stop()
stops the spinner. Takes no arguments. See BUGS section for potential problems with this method.
API
To create your own spinners, you just need to make a class and add a few methods.
REQUIRED
new()
A simple bless {}, $_[0];
will suffice. If you need more than that, feel free to add more. Your program will be calling new()
to initialize your spinner.
frames()
This method should return an array of frames for your spinner. If you have a dynamic spinner (see below), just return undef
.
speed()
This method should return how long to wait between each frame switch. If you have a dynamic spinner (see below), this method will be called multiple times.
OPTIONAL
dynamic()
Implementing this function (and returning true) indicates that you have a dynamic spinner. Dynamic spinners can change the speed that the spinner spins at between each frame, as well as being able to generate their frames dynamically. See the code of Acme::Spinners::Dynamic for an example.
get_next_frame()
If you implement dynamic()
(above), you must implement this function. This function is called between each spinner frame, and it should return the next spinner in the sequence.
BUGS
Hopefully, I have worked out the kinks in this module (well, the really obvious ones anyway). However, there are a few things you need to watch out for.
In the example code, you see how there's a small sleep after the stop. There's a reason for that. When you call stop()
, it sends a message for the child process to stop and clean up. If your program exits immediately after that, the child will NOT get a chance to clean up after itself, leading to a potentially garbled terminal. It does not have to be a sleep()
command, just make sure your program doesn't call stop()
and exit.
This module does not catch Unix signals. Care must be taken to possibly call stop()
(and wait to clean up).
This module forks. For the 0.01% of you without a working fork, you're on your own.
If you frequently kill your spinner applications, you will notice an accumulation of acme-spinner123456.flag
files. That is completely normal, and they can be deleted without side effects. (The flag files are my way of handling IPC. Feel free to propose a better one.)
I do not take responsibility for potential bugs in this module. This module has not been suitably tested for enterprise-level applications. Use at your own risk. (Heck, you shouldn't be using ANY Acme::* modules in an enterprise-level app.)
EXPORT
None by default. (OOP)
SEE ALSO
Your BIOS for an example of a simple text spinner.
This module not to be confused with Acme::Spinner.
AUTHOR
Noah Rankins, <cpan.20.kscript@spamgourmet.com<gt>
COPYRIGHT AND LICENSE
Copyright (c) 2007, Noah Rankins
All rights reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of Noah Rankins nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY NOAH RANKINS AND CONTRIBUTORS ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL NOAH RANKINS AND CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.