File Coverage

blib/lib/Acme/PlayCode.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Acme::PlayCode;
2              
3 9     9   248650 use Moose;
  0            
  0            
4             use PPI;
5             use Path::Class ();
6              
7             our $VERSION = '0.12';
8             our $AUTHORITY = 'cpan:FAYLAND';
9              
10             with 'MooseX::Object::Pluggable';
11              
12             has 'tokens' => (
13             is => 'rw',
14             isa => 'ArrayRef',
15             auto_deref => 1,
16             default => sub { [] },
17             );
18             has 'token_flag' => ( is => 'rw', isa => 'Num', default => 0 );
19              
20             has 'output' => (
21             is => 'rw',
22             isa => 'ArrayRef',
23             default => sub { [] }
24             );
25              
26             sub play {
27             my ( $self, $code, $opts ) = @_;
28            
29             my $file;
30             if ( $code !~ /\s/ and -e $code ) {
31             $file = Path::Class::File->new($code);
32             $code = $file->slurp();
33             }
34            
35             # clear to multi-run
36             $self->output( [] );
37             $self->token_flag( 0 );
38            
39             my $doc = PPI::Document->new( \$code );
40             $self->tokens( $doc->find('PPI::Token') );
41              
42             $self->do_with_tokens();
43            
44             my @output = @{ $self->output };
45             # check Acme::PlayCode::Plugin::PrintComma
46             @output = grep { $_ ne 'Acme::PlayCode::!@#$%^&*()_+' } @output;
47             my $output = join('', @output);
48             if ( $opts->{rewrite_file} and $file ) {
49             my $fh = $file->openw();
50             print $fh $output;
51             $fh->close();
52            
53             }
54             return $output;
55             }
56              
57             sub do_with_tokens {
58             my ( $self ) = @_;
59            
60             while ( $self->token_flag < scalar @{$self->tokens}) {
61             my $orginal_flag = $self->token_flag;
62             my $content = $self->do_with_token_flag( $self->token_flag );
63             push @{ $self->output }, $content if ( defined $content );
64             # if we don't move token_flag, ++
65             if ( $self->token_flag == $orginal_flag ) {
66             $self->token_flag( $self->token_flag + 1 );
67             }
68             }
69             }
70              
71             sub do_with_token_flag {
72             my ( $self, $token_flag ) = @_;
73            
74             my @tokens = $self->tokens;
75             my $token = $tokens[$token_flag];
76            
77             return $self->do_with_token( $token );
78             }
79              
80             sub do_with_token {
81             my ( $self, $token ) = @_;
82              
83             my $token_flag = $self->token_flag;
84             my @tokens = $self->tokens;
85             if ( $token->isa('PPI::Token::HereDoc') ) {
86             my @output = @{ $self->output };
87            
88             my @next_tokens;
89             my $old_flag = $token_flag;
90             while ( $old_flag++ ) {
91             push @next_tokens, $tokens[$old_flag];
92             last if ( $tokens[$old_flag]->content eq ';' );
93             }
94             push @output, $token->content,
95             join('', map { $_->content } @next_tokens ), "\n",
96             join('', $token->heredoc),
97             $token->terminator;
98            
99             # skip next itself and next ';'
100             $self->token_flag( $token_flag + 1 + scalar @next_tokens );
101             $self->output( \@output );
102             return;
103             } else {
104             return $token->content;
105             }
106             }
107              
108             no Moose;
109             __PACKAGE__->meta->make_immutable;
110              
111             1;
112             __END__
113              
114             =head1 NAME
115              
116             Acme::PlayCode - Code transforming to avoid typical typing mistakes
117              
118             =head1 SYNOPSIS
119              
120             use Acme::PlayCode;
121            
122             my $app = new Acme::PlayCode;
123            
124             $app->load_plugin('DoubleToSingle');
125             $app->load_plugin('ExchangeCondition');
126            
127             my $played_code = $app->play( $code );
128             # or
129             my $played_code = $app->play( $filename );
130             # or
131             $app->play( $filename, { rewrite_file => 1 } ); # override $filename with played code
132              
133             =head1 ALPHA WARNING
134              
135             L<Acme::PlayCode> is still in its infancy. No fundamental changes are expected, but
136             nevertheless backwards compatibility is not yet guaranteed.
137              
138             =head1 DESCRIPTION
139              
140             It aims to change the code to be better (to be worse if you want).
141              
142             More description and API detais will come later.
143              
144             =head1 PLUGINS
145              
146             =over 4
147              
148             =item L<Acme::PlayCode::Plugin::Averything>
149              
150             load all plugins we found.
151              
152             =item L<Acme::PlayCode::Plugin::DoubleToSingle>
153              
154             Play code with Single and Double
155              
156             =item L<Acme::PlayCode::Plugin::ExchangeCondition>
157              
158             Play code with exchanging condition
159              
160             =item L<Acme::PlayCode::Plugin::PrintComma>
161              
162             Play code with printing comma
163              
164             =item L<Acme::PlayCode::Plugin::NumberPlus>
165              
166             Play code with plus number
167              
168             =back
169              
170             =head1 SEE ALSO
171              
172             L<Moose>, L<PPI>, L<MooseX::Object::Pluggable>
173              
174             =head1 AUTHOR
175              
176             Fayland Lam, C<< <fayland at gmail.com> >>
177              
178             =head1 ACKNOWLEDGEMENTS
179              
180             The L<Moose> Team.
181              
182             Jens Rehsack, for the description (RT 53680)
183              
184             =head1 COPYRIGHT & LICENSE
185              
186             Copyright 2008 Fayland Lam, all rights reserved.
187              
188             This program is free software; you can redistribute it and/or modify it
189             under the same terms as Perl itself.
190              
191             =cut