File Coverage

blib/lib/Perl/ToPerl6/Command.pm
Criterion Covered Total %
statement 38 275 13.8
branch 0 112 0.0
condition 0 53 0.0
subroutine 13 39 33.3
pod 1 1 100.0
total 52 480 10.8


line stmt bran cond sub pod time code
1             package Perl::ToPerl6::Command;
2              
3 1     1   1885 use 5.006001;
  1         4  
4 1     1   5 use strict;
  1         2  
  1         24  
5 1     1   5 use warnings;
  1         2  
  1         35  
6              
7 1     1   5 use English qw< -no_match_vars >;
  1         3  
  1         10  
8 1     1   466 use Readonly;
  1         2  
  1         49  
9              
10 1     1   1100 use Getopt::Long qw< GetOptions >;
  1         10049  
  1         5  
11 1     1   150 use List::Util qw< first max >;
  1         3  
  1         65  
12 1     1   2150 use Pod::Usage qw< pod2usage >;
  1         60463  
  1         93  
13              
14 1     1   11 use Perl::ToPerl6::Exception::Parse ();
  1         2  
  1         22  
15 1         97 use Perl::ToPerl6::Utils qw<
16             :characters :severities transformer_short_name
17             $DEFAULT_VERBOSITY $DEFAULT_VERBOSITY_WITH_FILE_NAME
18 1     1   6 >;
  1         2  
19 1     1   370 use Perl::ToPerl6::Utils::Constants qw< $_MODULE_VERSION_TERM_ANSICOLOR >;
  1         2  
  1         77  
20 1     1   5 use Perl::ToPerl6::Transformation qw<>;
  1         2  
  1         31  
21              
22             #-----------------------------------------------------------------------------
23              
24             our $VERSION = '0.040';
25              
26             #-----------------------------------------------------------------------------
27              
28 1     1   4 use Exporter 'import';
  1         3  
  1         3377  
29              
30             Readonly::Array our @EXPORT_OK => qw< run >;
31              
32             Readonly::Hash our %EXPORT_TAGS => ( all => [ @EXPORT_OK ] );
33              
34             #-----------------------------------------------------------------------------
35              
36             Readonly::Scalar my $DEFAULT_VIOLATIONS_FOR_TOP => 20;
37              
38             Readonly::Scalar my $EXIT_SUCCESS => 0;
39             Readonly::Scalar my $EXIT_NO_FILES => 1;
40             Readonly::Scalar my $EXIT_HAD_FILE_PROBLEMS => 2;
41              
42             #-----------------------------------------------------------------------------
43              
44             my @files = ();
45             my $mogrify = undef;
46             my $output = \*STDOUT;
47              
48             #-----------------------------------------------------------------------------
49              
50             sub _out {
51 0     0     my @lines = @_;
52 0           return print {$output} @lines;
  0            
53             }
54              
55             #-----------------------------------------------------------------------------
56              
57             sub run {
58 0     0 1   my %options = _get_options();
59 0           @files = _get_input(@ARGV);
60              
61 0           my ($transformations, $had_error_in_file) = _transform(\%options, @files);
62              
63 0 0         return $EXIT_HAD_FILE_PROBLEMS if $had_error_in_file;
64 0 0         return $EXIT_NO_FILES if not defined $transformations;
65              
66 0           return $EXIT_SUCCESS;
67             }
68              
69             #-----------------------------------------------------------------------------
70              
71             sub _get_options {
72              
73 0     0     my %opts = _parse_command_line();
74 0           _dispatch_special_requests( %opts );
75 0           _validate_options( %opts );
76              
77             # Convert necessity shortcut options. If multiple shortcuts
78             # are given, the lowest one wins. If an explicit --necessity
79             # option has been given, then the shortcuts are ignored. The
80             # @NECESSITY_NAMES variable is exported by Perl::ToPerl6::Utils.
81 0   0 0     $opts{-necessity} ||= first { exists $opts{"-$_"} } @NECESSITY_NAMES;
  0            
82 0   0 0     $opts{-necessity} ||= first { exists $opts{"-$_"} } ($NECESSITY_LOWEST .. $NECESSITY_HIGHEST);
  0            
83              
84              
85             # If --top is specified, default the necessity level to 1, unless an
86             # explicit necessity is defined. This provides us flexibility to
87             # report top-offenders across just some or all of the necessity levels.
88             # We also default the --top count to twenty if none is given
89 0 0         if ( exists $opts{-top} ) {
90 0   0       $opts{-necessity} ||= 1;
91 0   0       $opts{-top} ||= $DEFAULT_VIOLATIONS_FOR_TOP;
92             }
93              
94             #Override profile, if --noprofile is specified
95 0 0         if ( exists $opts{-noprofile} ) {
96 0           $opts{-profile} = $EMPTY;
97             }
98              
99 0           return %opts;
100             }
101              
102             #-----------------------------------------------------------------------------
103              
104             sub _parse_command_line {
105 0     0     my %opts;
106 0           my @opt_specs = _get_option_specification();
107 0           Getopt::Long::Configure('no_ignore_case');
108 0 0         GetOptions( \%opts, @opt_specs ) || pod2usage(); #Exits
109              
110             # I've adopted the convention of using key-value pairs for
111             # arguments to most functions. And to increase legibility,
112             # I have also adopted the familiar command-line practice
113             # of denoting argument names with a leading dash (-).
114 0           my %dashed_opts = map { ( "-$_" => $opts{$_} ) } keys %opts;
  0            
115 0           return %dashed_opts;
116             }
117              
118             #-----------------------------------------------------------------------------
119              
120             sub _dispatch_special_requests {
121 0     0     my (%opts) = @_;
122 0 0         if ( $opts{-help} ) { pod2usage( -verbose => 0 ) } # Exits
  0            
123 0 0         if ( $opts{-options} ) { pod2usage( -verbose => 1 ) } # Exits
  0            
124 0 0         if ( $opts{-man} ) { pod2usage( -verbose => 2 ) } # Exits
  0            
125 0 0         if ( $opts{-version} ) { _display_version() } # Exits
  0            
126 0 0         if ( $opts{-list} ) { _render_all_transformer_listing() } # Exits
  0            
127 0 0         if ( $opts{'-list-enabled'} ) { _render_transformer_listing(%opts) } # Exits
  0            
128 0 0         if ( $opts{'-list-themes'} ) { _render_theme_listing() } # Exits
  0            
129 0 0         if ( $opts{'-profile-proto'} ) { _render_profile_prototype() } # Exits
  0            
130 0 0         if ( $opts{-doc} ) { _render_transformer_docs( %opts ) } # Exits
  0            
131 0           return 1;
132             }
133              
134             #-----------------------------------------------------------------------------
135              
136             sub _validate_options {
137 0     0     my (%opts) = @_;
138 0           my $msg = $EMPTY;
139              
140              
141 0 0 0       if ( $opts{-noprofile} && $opts{-profile} ) {
142 0           $msg .= qq{Warning: Cannot use -noprofile with -profile option.\n};
143             }
144              
145 0 0 0       if ( $opts{-verbose} && $opts{-verbose} !~ m{(?: \d+ | %[mfFlcCedrpPs] )}xms) {
146 0           $msg .= qq<Warning: --verbose arg "$opts{-verbose}" looks odd. >;
147 0           $msg .= qq<Perhaps you meant to say "--verbose 3 $opts{-verbose}."\n>;
148             }
149              
150 0 0 0       if ( exists $opts{-top} && $opts{-top} < 0 ) {
151 0           $msg .= qq<Warning: --top argument "$opts{-top}" is negative. >;
152 0           $msg .= qq<Perhaps you meant to say "$opts{-top} --top".\n>;
153             }
154              
155 0 0 0       if (
      0        
156             exists $opts{-necessity}
157             && (
158             $opts{-necessity} < $NECESSITY_LOWEST
159             || $opts{-necessity} > $NECESSITY_HIGHEST
160             )
161             ) {
162 0           $msg .= qq<Warning: --necessity arg "$opts{-necessity}" out of range. >;
163 0           $msg .= qq<Severities range from "$NECESSITY_LOWEST" (lowest) to >;
164 0           $msg .= qq<"$NECESSITY_HIGHEST" (highest).\n>;
165             }
166              
167              
168 0 0         if ( $msg ) {
169 0           pod2usage( -exitstatus => 1, -message => $msg, -verbose => 0); #Exits
170             }
171              
172              
173 0           return 1;
174             }
175              
176             #-----------------------------------------------------------------------------
177              
178             sub _get_input {
179              
180 0     0     my @args = @_;
181              
182 0 0 0       if ( !@args || (@args == 1 && $args[0] eq q{-}) ) {
      0        
183              
184             # Reading code from STDIN. All the code is slurped into
185             # a string. PPI will barf if the string is just whitespace.
186 0           my $code_string = do { local $RS = undef; <STDIN> };
  0            
  0            
187              
188             # Notice if STDIN was closed (pipe error, etc)
189 0 0         if ( ! defined $code_string ) {
190 0           $code_string = $EMPTY;
191             }
192              
193 0 0         $code_string =~ m{ \S+ }xms || die qq{Nothing to transform.\n};
194 0           return \$code_string; #Convert to SCALAR ref for PPI
195             }
196             else {
197              
198             # Test to make sure all the specified files or directories
199             # actually exist. If any one of them is bogus, then die.
200 0 0   0     if ( my $nonexistent = first { ! -e } @args ) {
  0            
201 0           my $msg = qq{No such file or directory: '$nonexistent'};
202 0           pod2usage( -exitstatus => 1, -message => $msg, -verbose => 0);
203             }
204              
205             # Reading code from files or dirs. If argument is a file,
206             # then we process it as-is (even though it may not actually
207             # be Perl code). If argument is a directory, recursively
208             # search the directory for files that look like Perl code.
209 0 0         return map { (-d) ? Perl::ToPerl6::Utils::all_perl_files($_) : $_ } @args;
  0            
210             }
211             }
212              
213             #------------------------------------------------------------------------------
214              
215             sub _transform {
216              
217 0     0     my ( $opts_ref, @files_to_transform ) = @_;
218 0 0         @files_to_transform || die "No perl files were found.\n";
219              
220             # Perl::ToPerl6 has lots of dependencies, so loading is delayed
221             # until it is really needed. This hack reduces startup time for
222             # doing other things like getting the version number or dumping
223             # the man page. Arguably, those things are pretty rare, but hey,
224             # why not save a few seconds if you can.
225              
226 0           require Perl::ToPerl6;
227 0           $mogrify = Perl::ToPerl6->new( %{$opts_ref} );
  0            
228 0 0         $mogrify->transformers() || die "No transformers selected.\n";
229              
230 0           _set_up_pager($mogrify->config()->pager());
231              
232 0           my $number_of_transformations = undef;
233 0           my $had_error_in_file = 0;
234              
235 0           for my $file (@files_to_transform) {
236              
237             eval {
238 0           my @transformations = $mogrify->transform($file);
239 0           $number_of_transformations += scalar @transformations;
240              
241 0 0         if (not $opts_ref->{'-statistics-only'}) {
242 0           _render_report( $file, $opts_ref, @transformations )
243             }
244 0           1;
245             }
246 0 0         or do {
247 0 0         if ( my $exception = Perl::ToPerl6::Exception::Parse->caught() ) {
    0          
248 0           $had_error_in_file = 1;
249 0           warn qq<Problem while mogrifying "$file": $EVAL_ERROR\n>;
250             }
251             elsif ($EVAL_ERROR) {
252             # P::C::Exception::Fatal includes the stack trace in its
253             # stringification.
254 0           die qq<Fatal error while mogrifying "$file": $EVAL_ERROR\n>;
255             }
256             else {
257 0           die qq<Fatal error while mogrifying "$file". Unfortunately, >,
258             q<$@/$EVAL_ERROR >,
259             qq<is empty, so the reason can't be shown.\n>;
260             }
261             }
262             }
263              
264 0 0 0       if ( $opts_ref->{-statistics} or $opts_ref->{'-statistics-only'} ) {
265 0           my $stats = $mogrify->statistics();
266 0           _report_statistics( $opts_ref, $stats );
267             }
268              
269 0           return $number_of_transformations, $had_error_in_file;
270             }
271              
272             #------------------------------------------------------------------------------
273              
274             sub _render_report {
275 0     0     my ( $file, $opts_ref, @transformations ) = @_;
276              
277             # Only report the files, if asked.
278 0           my $number_of_transformations = scalar @transformations;
279 0 0 0       if ( $opts_ref->{'-files-with-transformations'} ||
280             $opts_ref->{'-files-without-transformations'} ) {
281             not ref $file
282 0 0 0       and $opts_ref->{$number_of_transformations ? '-files-with-transformations' :
    0          
283             '-files-without-transformations'}
284             and _out "$file\n";
285 0           return $number_of_transformations;
286             }
287              
288             # Only report the number of transformations, if asked.
289 0 0         if( $opts_ref->{-count} ){
290 0 0         ref $file || _out "$file: ";
291 0           _out "$number_of_transformations\n";
292 0           return $number_of_transformations;
293             }
294              
295             # Hail all-clear unless we should shut up.
296 0 0 0       if( !@transformations && !$opts_ref->{-quiet} ) {
297 0 0         ref $file || _out "$file ";
298 0           _out "source OK\n";
299 0           return 0;
300             }
301              
302             # Otherwise, format and print transformations
303 0           my $verbosity = $mogrify->config->verbose();
304             # $verbosity can be numeric or string, so use "eq" for comparison;
305 0 0 0       $verbosity =
306             ($verbosity eq $DEFAULT_VERBOSITY && @files > 1)
307             ? $DEFAULT_VERBOSITY_WITH_FILE_NAME
308             : $verbosity;
309 0           my $fmt = Perl::ToPerl6::Utils::verbosity_to_format( $verbosity );
310 0 0         if (not -f $file) { $fmt =~ s< \%[fF] ><STDIN>xms; } #HACK!
  0            
311 0           Perl::ToPerl6::Transformation::set_format( $fmt );
312              
313 0           my $color = $mogrify->config->color();
314 0 0         if ( $mogrify->config->detail() ) {
315             @transformations = grep {
316 0           $_->necessity <= $mogrify->config->detail()
  0            
317             } @transformations;
318             }
319 0 0         _out $color ? _colorize_by_necessity(@transformations) : @transformations;
320              
321 0           return $number_of_transformations;
322             }
323              
324             #-----------------------------------------------------------------------------
325              
326             sub _set_up_pager {
327 0     0     my ($pager_command) = @_;
328 0 0         return if not $pager_command;
329 0 0         return if not _at_tty();
330              
331 0 0         open my $pager, q<|->, $pager_command
332             or die qq<Unable to pipe to pager "$pager_command": $ERRNO\n>;
333              
334 0           $output = $pager;
335              
336 0           return;
337             }
338              
339             #-----------------------------------------------------------------------------
340              
341             sub _report_statistics {
342 0     0     my ($opts_ref, $statistics) = @_;
343              
344 0 0 0       if (
      0        
345             not $opts_ref->{'-statistics-only'}
346             and (
347             $statistics->total_transformations()
348             or not $opts_ref->{-quiet} and $statistics->modules()
349             )
350             ) {
351 0           _out "\n"; # There's prior output that we want to separate from.
352             }
353              
354 0           my $files = _commaify($statistics->modules());
355 0           my $subroutines = _commaify($statistics->subs());
356 0           my $statements = _commaify($statistics->statements_other_than_subs());
357 0           my $lines = _commaify($statistics->lines());
358 0           my $width = max map { length } $files, $subroutines, $statements;
  0            
359              
360 0           _out sprintf "%*s %s.\n", $width, $files, 'files';
361 0           _out sprintf "%*s %s.\n", $width, $subroutines, 'subroutines/methods';
362 0           _out sprintf "%*s %s.\n", $width, $statements, 'statements';
363              
364 0           _out _commaify($statistics->total_transformations()), " transformations.\n";
365              
366 0           my $transformations_per_file = $statistics->transformations_per_file();
367 0 0         if (defined $transformations_per_file) {
368 0           _out
369             sprintf
370             "Transformations per file was %.3f.\n",
371             $transformations_per_file;
372             }
373 0           my $transformations_per_statement = $statistics->transformations_per_statement();
374 0 0         if (defined $transformations_per_statement) {
375 0           _out
376             sprintf
377             "Transformations per statement was %.3f.\n",
378             $transformations_per_statement;
379             }
380 0           my $transformations_per_line = $statistics->transformations_per_line_of_code();
381 0 0         if (defined $transformations_per_line) {
382 0           _out
383             sprintf
384             "Transformations per line of code was %.3f.\n",
385             $transformations_per_line;
386             }
387              
388 0 0         if ( $statistics->total_transformations() ) {
389 0           _out "\n";
390              
391 0           my %necessity_transformations = %{ $statistics->transformations_by_necessity() };
  0            
392 0           my @severities = reverse sort keys %necessity_transformations;
393             $width =
394             max
395 0           map { length _commaify( $necessity_transformations{$_} ) }
  0            
396             @severities;
397 0           foreach my $necessity (@severities) {
398             _out
399             sprintf
400             "%*s necessity %d transformations.\n",
401             $width,
402 0           _commaify( $necessity_transformations{$necessity} ),
403             $necessity;
404             }
405              
406 0           _out "\n";
407              
408 0           my %transformer_transformations = %{ $statistics->transformations_by_transformer() };
  0            
409 0           my @transformers = sort keys %transformer_transformations;
410             $width =
411             max
412 0           map { length _commaify( $transformer_transformations{$_} ) }
  0            
413             @transformers;
414 0           foreach my $transformer (@transformers) {
415             _out
416             sprintf
417             "%*s transformations of %s.\n",
418             $width,
419 0           _commaify($transformer_transformations{$transformer}),
420             transformer_short_name($transformer);
421             }
422             }
423              
424 0           return;
425             }
426              
427             #-----------------------------------------------------------------------------
428              
429             # Only works for integers.
430             sub _commaify {
431 0     0     my ( $number ) = @_;
432              
433 0           while ($number =~ s/ \A ( [-+]? \d+ ) ( \d{3} ) /$1,$2/xms) {
434             # nothing
435             }
436              
437 0           return $number;
438             }
439              
440             #-----------------------------------------------------------------------------
441              
442             sub _get_option_specification {
443              
444 0     0     return qw<
445             5 4 3 2 1
446             Safari
447             version
448             brutal
449             count|C
450             cruel
451             doc=s
452             exclude=s@
453             force!
454             gentle
455             harsh
456             help|?|H
457             include=s@
458             list
459             list-enabled
460             list-themes
461             man
462             color|colour!
463             noprofile
464             in-place!
465             only!
466             options
467             pager=s
468             profile|p=s
469             profile-proto
470             quiet
471             necessity=i
472             detail=i
473             single-transformer|s=s
474             stern
475             statistics!
476             statistics-only!
477             profile-strictness=s
478             theme=s
479             top:i
480             verbose=s
481             color-necessity-highest|colour-necessity-highest|color-necessity-5|colour-necessity-5=s
482             color-necessity-high|colour-necessity-high|color-necessity-4|colour-necessity-4=s
483             color-necessity-medium|colour-necessity-medium|color-necessity-3|colour-necessity-3=s
484             color-necessity-low|colour-necessity-low|color-necessity-2|colour-necessity-2=s
485             color-necessity-lowest|colour-necessity-lowest|color-necessity-1|colour-necessity-1=s
486             files-with-transformations|l
487             files-without-transformations|L
488             program-extensions=s@
489             >;
490             }
491              
492             #-----------------------------------------------------------------------------
493              
494             sub _colorize_by_necessity {
495 0     0     my @transformations = @_;
496 0 0         return @transformations if _this_is_windows();
497 0 0         return @transformations if not eval {
498 0           require Term::ANSIColor;
499 0           Term::ANSIColor->VERSION( $_MODULE_VERSION_TERM_ANSICOLOR );
500 0           1;
501             };
502              
503 0           my $config = $mogrify->config();
504 0           my %color_of = (
505             $NECESSITY_HIGHEST => $config->color_necessity_highest(),
506             $NECESSITY_HIGH => $config->color_necessity_high(),
507             $NECESSITY_MEDIUM => $config->color_necessity_medium(),
508             $NECESSITY_LOW => $config->color_necessity_low(),
509             $NECESSITY_LOWEST => $config->color_necessity_lowest(),
510             );
511              
512 0           return map { _colorize( "$_", $color_of{$_->necessity()} ) } @transformations;
  0            
513              
514             }
515              
516             #-----------------------------------------------------------------------------
517              
518             sub _colorize {
519 0     0     my ($string, $color) = @_;
520 0 0         return $string if not defined $color;
521 0 0         return $string if $color eq $EMPTY;
522             # $terminator is a purely cosmetic change to make the color end at the end
523             # of the line rather than right before the next line. It is here because
524             # if you use background colors, some console windows display a little
525             # fragment of colored background before the next uncolored (or
526             # differently-colored) line.
527 0 0         my $terminator = chomp $string ? "\n" : $EMPTY;
528 0           return Term::ANSIColor::colored( $string, $color ) . $terminator;
529             }
530              
531             #-----------------------------------------------------------------------------
532              
533             sub _this_is_windows {
534 0 0   0     return 1 if $OSNAME =~ m/MSWin32/xms;
535 0           return 0;
536             }
537              
538             #-----------------------------------------------------------------------------
539              
540             sub _at_tty {
541 0     0     return -t STDOUT;
542             }
543              
544             #-----------------------------------------------------------------------------
545              
546             sub _render_all_transformer_listing {
547             # Force P-C parameters, to catch all Transformers on this site
548 0     0     my %pc_params = (-profile => $EMPTY, -necessity => $NECESSITY_LOWEST);
549 0           return _render_transformer_listing( %pc_params );
550             }
551              
552             #-----------------------------------------------------------------------------
553              
554             sub _render_transformer_listing {
555 0     0     my %pc_params = @_;
556              
557 0           require Perl::ToPerl6::TransformerListing;
558 0           require Perl::ToPerl6;
559              
560 0           my @transformers = Perl::ToPerl6->new( %pc_params )->transformers();
561 0           my $listing = Perl::ToPerl6::TransformerListing->new( -transformers => \@transformers );
562 0           _out $listing;
563              
564 0           exit $EXIT_SUCCESS;
565             }
566              
567             #-----------------------------------------------------------------------------
568              
569             sub _render_theme_listing {
570              
571 0     0     require Perl::ToPerl6::ThemeListing;
572 0           require Perl::ToPerl6;
573              
574 0           my %pc_params = (-profile => $EMPTY, -necessity => $NECESSITY_LOWEST);
575 0           my @transformers = Perl::ToPerl6->new( %pc_params )->transformers();
576 0           my $listing = Perl::ToPerl6::ThemeListing->new( -transformers => \@transformers );
577 0           _out $listing;
578              
579 0           exit $EXIT_SUCCESS;
580             }
581              
582             #-----------------------------------------------------------------------------
583              
584             sub _render_profile_prototype {
585              
586 0     0     require Perl::ToPerl6::ProfilePrototype;
587 0           require Perl::ToPerl6;
588              
589 0           my %pc_params = (-profile => $EMPTY, -necessity => $NECESSITY_LOWEST);
590 0           my @transformers = Perl::ToPerl6->new( %pc_params )->transformers();
591 0           my $prototype = Perl::ToPerl6::ProfilePrototype->new( -transformers => \@transformers );
592 0           _out $prototype;
593              
594 0           exit $EXIT_SUCCESS;
595             }
596              
597             #-----------------------------------------------------------------------------
598              
599             sub _render_transformer_docs {
600              
601 0     0     my (%opts) = @_;
602 0           my $pattern = delete $opts{-doc};
603              
604 0           require Perl::ToPerl6;
605 0           $mogrify = Perl::ToPerl6->new(%opts);
606 0           _set_up_pager($mogrify->config()->pager());
607              
608 0           require Perl::ToPerl6::TransformerFactory;
609 0           my @site_transformers = Perl::ToPerl6::TransformerFactory->site_transformer_names();
610 0           my @matching_transformers = grep { /$pattern/ixms } @site_transformers;
  0            
611              
612             # "-T" means don't send to pager
613 0           my @perldoc_output = map {`perldoc -T $_`} @matching_transformers;
  0            
614 0           _out @perldoc_output;
615              
616 0           exit $EXIT_SUCCESS;
617             }
618              
619             #-----------------------------------------------------------------------------
620              
621             sub _display_version {
622 0     0     _out "$VERSION\n";
623 0           exit $EXIT_SUCCESS;
624             }
625              
626             #-----------------------------------------------------------------------------
627             1;
628              
629             __END__
630              
631             #-----------------------------------------------------------------------------
632              
633             =pod
634              
635             =for stopwords
636             Twitter
637              
638             =head1 NAME
639              
640             Perl::ToPerl6::Command - Guts of L<perlmogrify|perlmogrify>.
641              
642              
643             =head1 SYNOPSIS
644              
645             use Perl::ToPerl6::Command qw< run >;
646              
647             local @ARGV = qw< --statistics-only lib bin >;
648             run();
649              
650              
651             =head1 DESCRIPTION
652              
653             This is the implementation of the L<perlmogrify|perlmogrify> command. You can use
654             this to run the command without going through a command interpreter.
655              
656              
657             =head1 INTERFACE SUPPORT
658              
659             This is considered to be a public class. However, its interface is
660             experimental, and will likely change.
661              
662              
663             =head1 IMPORTABLE SUBROUTINES
664              
665             =over
666              
667             =item C<run()>
668              
669             Does the equivalent of the L<perlmogrify|perlmogrify> command. Unfortunately, at
670             present, this doesn't take any parameters but uses C<@ARGV> to get its
671             input instead. Count on this changing; don't count on the current
672             interface.
673              
674              
675             =back
676              
677              
678             =head1 TO DO
679              
680             Make C<run()> take parameters. The equivalent of C<@ARGV> should be
681             passed as a reference.
682              
683             Turn this into an object.
684              
685              
686             =head1 AUTHOR
687              
688             Jeffrey Goff <drforr@pobox.com>
689              
690              
691             =head1 AUTHOR EMERITUS
692              
693             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
694              
695              
696             =head1 COPYRIGHT
697              
698             Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
699              
700             This program is free software; you can redistribute it and/or modify
701             it under the same terms as Perl itself. The full text of this license
702             can be found in the LICENSE file included with this module.
703              
704             =cut
705              
706             ##############################################################################
707             # Local Variables:
708             # mode: cperl
709             # cperl-indent-level: 4
710             # fill-column: 78
711             # indent-tabs-mode: nil
712             # c-indentation-style: bsd
713             # End:
714             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :