File Coverage

blib/lib/Term/Spinner.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Term::Spinner;
2              
3 2     2   36563 use strict;
  2         4  
  2         75  
4 2     2   9 use warnings;
  2         3  
  2         46  
5 2     2   40 use 5.006_000;
  2         5  
  2         105  
6             our $VERSION = '0.01';
7              
8             =head1 NAME
9              
10             Term::Spinner - A progress spinner for commandline programs
11              
12             =head1 SYNOPSIS
13              
14             use Term::Spinner;
15              
16             my $spinner = Term::Spinner->new();
17             while(... doing something ...) {
18             $spinner->advance();
19             # Do things...
20             }
21             undef $spinner; # clears final spinner output by default.
22              
23             =head1 DESCRIPTION
24              
25             This module provides a simple one-character spinner for commandline
26             programs. You can use this to keep the user from getting bored
27             while your program performs a long operation.
28              
29             You can override the array of graphical characters used to draw
30             the spinner (by default, C<-, \, |, /,> and C<x> for "finished").
31              
32             It clears the spinner for re-drawing by using a sequence
33             of backspace, space, backspace. I've found this works for me
34             on all of the terminals I use, without having to get into all
35             the C<$TERM> types and various special escape sequences.
36              
37             In the future, I may add support for using escape sequences for
38             well-known terminal types, if it can be done reliably.
39              
40             Try C<perl examples/various.pl> in this distribution to see
41             some sample spinners in action.
42              
43             =cut
44              
45 2     2   8 use Carp qw/croak/;
  2         3  
  2         161  
46 2     2   1121 use IO::Handle;
  2         11501  
  2         94  
47              
48 2     2   516 use Moose;
  0            
  0            
49              
50             =head1 ATTRIBUTES
51              
52             These can be used as options to C<new>, or modified at any
53             time by calling them as accessors on an object.
54              
55             =head2 spin_chars
56              
57             An arrayref of characters used to draw the spinner. The default
58             is C<-, \, |, /, x>. The final character of this array is not
59             used during the normal spin cycle, it is used when you call
60             L</finish>, to indicate the spinner is done spinning.
61              
62             =cut
63              
64             has 'spin_chars' => (
65             is => 'rw',
66             isa => 'ArrayRef',
67             default => sub { ['-', '\\', '|', '/', 'x'] },
68             );
69              
70             has '_spinner' => (
71             is => 'rw',
72             isa => 'Int',
73             default => 0,
74             );
75              
76             has '_drawn' => (
77             is => 'rw',
78             isa => 'Int',
79             default => 0,
80             );
81              
82             =head2 output_handle
83              
84             The filehandle to use when drawing the spinner. Defaults to
85             C<STDERR>.
86              
87             =cut
88              
89             has 'output_handle' => (
90             is => 'rw',
91             isa => 'FileHandle',
92             default => sub { \*STDERR },
93             trigger => sub { $_[1]->autoflush(1) },
94             );
95              
96             =head2 clear_on_destruct
97              
98             Boolean setting for whether the spinner should L</clear> itself
99             when the object is destructed. Defaults to true.
100              
101             =cut
102              
103             has 'clear_on_destruct' => (
104             is => 'rw',
105             isa => 'Bool',
106             default => 1,
107             );
108              
109             =head2 finish_on_destruct
110              
111             Boolean setting for whether the spinner should L</finish> itself
112             when the object is destructed. Defaults to true. Has little
113             noticeable effect if L</clear_on_destruct> is also enabled, as
114             the finish character will be cleared immediately.
115              
116             =cut
117              
118             has 'finish_on_destruct' => (
119             is => 'rw',
120             isa => 'Bool',
121             default => 1,
122             );
123              
124             =head1 METHODS
125              
126             =head2 new
127              
128             Provided by Moose. Accepts the attributes above as a simple
129             hash. Example:
130              
131             my $sp = Term::Spinner->new(
132             clear_on_destruct => 0,
133             output_handle => \*STDOUT,
134             );
135              
136             =head2 clear
137              
138             Clears the spinner's output, if any.
139              
140             $sp->clear();
141              
142             =cut
143              
144             sub clear {
145             my ($self) = @_;
146              
147             $self->output_handle->print("\010 \010") if $self->_drawn;
148             $self->_drawn(0);
149             }
150              
151             =head2 draw
152              
153             Draws the spinner in its current state, clearing first.
154             This is done automatically on L</advance> and L</finish>
155              
156             $sp->draw();
157              
158             =cut
159              
160             sub draw {
161             my ($self) = @_;
162              
163             $self->clear();
164             $self->output_handle->print($self->spin_chars->[$self->_spinner]);
165             $self->_drawn(1);
166             }
167              
168             =head2 advance
169              
170             Advance the spinner by one character and redraw.
171              
172             $sp->advance();
173              
174             =cut
175              
176             sub advance {
177             my ($self) = @_;
178              
179             $self->_spinner(($self->_spinner + 1) % $#{$self->spin_chars});
180             $self->draw();
181             }
182              
183             =head2 finish
184              
185             Set the spinner to the finish character and redraw
186              
187             $sp->finish();
188              
189             =cut
190              
191             sub finish {
192             my ($self) = @_;
193              
194             $self->_spinner($#{$self->spin_chars});
195             $self->draw();
196             }
197              
198             sub _destruct_cleanup {
199             my ($self) = @_;
200              
201             $self->finish if $self->finish_on_destruct;
202             $self->clear if $self->clear_on_destruct;
203             }
204              
205             =head2 DEMOLISH
206              
207             Our Moose destructor, handles finish/clear on destruct,
208             if not disabled.
209              
210             =cut
211              
212             =head2 meta
213              
214             Moose meta info.
215              
216             =cut
217              
218             sub DEMOLISH { shift->_destruct_cleanup }
219              
220             no Moose;
221              
222             =head1 AUTHOR
223              
224             Brandon L. Black, E<lt>blblack@gmail.comE<gt>
225              
226             =head1 COPYRIGHT AND LICENSE
227              
228             Copyright 2007 Brandon L. Black
229              
230             This library is free software; you can redistribute it and/or modify
231             it under the same terms as Perl itself.
232              
233             =cut
234              
235             1;