1App::Rad(3) User Contributed Perl Documentation App::Rad(3)
2
3
4
6 App::Rad - Rapid (and easy!) creation of command line applications
7
9 Version 1.04
10
12 This is your smallest working application (let's call it myapp.pl)
13
14 use App::Rad;
15 App::Rad->run();
16
17 That's it, your program already works and you can use it directly via
18 the command line (try it!)
19
20 [user@host]$ ./myapp.pl
21 Usage: myapp.pl command [arguments]
22
23 Available Commands:
24 help show syntax and available commands
25
26 Next, start creating your own functions (e.g.) inside myapp.pl:
27
28 sub hello {
29 return "Hello, World!";
30 }
31
32 And now your simple command line program myapp.pl has a 'hello'
33 command!
34
35 [user@host]$ ./myapp.pl
36 Usage: myapp.pl command [arguments]
37
38 Available Commands:
39 hello
40 help show syntax and available commands
41
42
43 [user@host]$ ./myapp.pl hello
44 Hello, World!
45
46 You could easily add a customized help message for your command through
47 the 'Help()' attribute:
48
49 sub hello
50 :Help(give a nice compliment)
51 {
52 return "Hello, World!";
53 }
54
55 And then, as expected:
56
57 [user@host]$ ./myapp.pl
58 Usage: myapp.pl command [arguments]
59
60 Available Commands:
61 hello give a nice compliment
62 help show syntax and available commands
63
64 App::Rad also lets you expand your applications, providing a lot of
65 flexibility for every command, with embedded help, argument and options
66 parsing, configuration file, default behavior, and much more:
67
68 use App::Rad;
69 App::Rad->run();
70
71 sub setup {
72 my $c = shift;
73
74 $c->register_commands( {
75 foo => 'expand your foo!',
76 bar => 'have a drink! arguments: --drink=DRINK',
77 });
78 }
79
80 sub foo {
81 my $c = shift;
82 $c->load_config('myapp.conf');
83
84 return 'foo expanded to ' . baz() * $c->config->{'myfoo'};
85 }
86
87 # note that 'baz' was not registered as a command,
88 # so it can't be called from the outside.
89 sub baz { rand(10) }
90
91 sub bar {
92 my $c = shift;
93 if ( $c->options->{'drink'} ) {
94 return 'you asked for a ' . $c->options->{'drink'};
95 }
96 else {
97 return 'you need to ask for a drink';
98 }
99 }
100
101 You can try on the command line:
102
103 [user@host]$ ./myapp.pl
104 Usage: myapp.pl command [arguments]
105
106 Available Commands:
107 bar have a drink! arguments: --drink=DRINK
108 foo expand your foo!
109 help show syntax and available commands
110
111
112 [user@host]$ ./myapp.pl bar --drink=martini
113 you asked for a martini
114
116 This module is very young, likely to change in strange ways and to have
117 some bugs (please report if you find any!). I will try to keep the API
118 stable, but even that is subject to change (let me know if you find
119 anything annoying or have a wishlist). You have been warned!
120
122 App::Rad aims to be a simple yet powerful framework for developing your
123 command-line applications. It can easily transform your Perl one-liners
124 into reusable subroutines than can be called directly by the user of
125 your program.
126
127 It also tries to provide a handy interface for your common command-line
128 tasks. If you have a feature request to easen out your tasks even more,
129 please drop me an email or a RT feature request.
130
131 Extending App::Rad - Plugins!
132 App::Rad plugins can be loaded by naming them as arguments to the "use
133 App::Rad" statement. Just ommit the "App::Rad::Plugin" prefix from the
134 plugin name. For example:
135
136 use App::Rad qw(My::Module);
137
138 will load the "App::Rad::Plugin::My::Module" plugin for you!
139
140 Developers are strongly encouraged to publish their App::Rad plugins
141 under the "App::Rad::Plugin" namespace. But, if your plugin start with
142 a name other than that, you can fully qualify the name by using an
143 unary plus sign:
144
145 use App::Rad qw(
146 My::Module
147 +Fully::Qualified::Plugin::Name
148 );
149
150 Note that plugins are loaded in the order in which they appear.
151
152 Please refer to the actual plugin documentation for specific usage. And
153 check out App::Rad::Plugin if you want to create your own plugins.
154
156 These are the main execution calls for the application. In your
157 App::Rad programs, the *ONLY* thing your script needs to actually (and
158 actively) call is one of the instantiation (or dispatcher) methods.
159 Leave all the rest to your subs. Currently, the only available
160 dispatcher is run():
161
162 run()
163 You'll be able to access all of your program's commands directly
164 through the command line, as shown in the synopsis.
165
167 This module comes with the following default commands. You are free to
168 override them as you see fit.
169
170 help
171 Shows help information for your program. This built-in function
172 displays the program name and all available commands (including the
173 ones you added yourself) if a user types the 'help' command, or no
174 command at all, or any command that does not exist (as they'd fall into
175 the 'default' control function which (by default) calls 'help').
176
177 You can also display specific embedded help for your commands, either
178 explicitly registering them with "$c->register()" or
179 "$c->register_commands()" inside "$c->setup()" (see respective sections
180 below) or with the Help() attribute:
181
182 use App::Rad;
183 App::Rad->run();
184
185 sub mycmd
186 :Help(display a nice welcome message)
187 {
188 return "Welcome!";
189 }
190
191 the associated help text would go like this:
192
193 [user@host]$ ./myapp.pl
194 Usage: myapp.pl command [arguments]
195
196 Available Commands:
197 help show syntax and available commands
198 mycmd display a nice welcome message
199
201 The 'include' and 'exclude' commands below let the user include and
202 exclude commands to your program and, as this might be dangerous when
203 the user is not yourself, you have to opt-in on them:
204
205 use App::Rad qw(include); # add the 'include' command
206 use App::Rad qw(exclude); # add the 'exclude' command
207
208 though you'll probably want to set them both:
209
210 use App::Rad qw(include exclude);
211
212 include [command_name] -perl_params 'your subroutine code'
213 Includes the given subroutine into your program on-the-fly, just as you
214 would writing it directly into your program.
215
216 Let's say you have your simple 'myapp.pl' program that uses App::Rad
217 sitting on your system quietly. One day, perhaps during your sysadmin's
218 tasks, you create a really amazing one-liner to solve a really hairy
219 problem, and want to keep it for posterity (reusability is always a
220 good thing!).
221
222 For instance, to change a CSV file in place, adding a column on
223 position #2 containing the line number, you might do something like
224 this (this is merely illustrative, it's not actually the best way to do
225 it):
226
227 $ perl -i -paF, -le 'splice @F,1,0,$.; $_=join ",",@F' somesheet.csv
228
229 And you just found out that you might use this other times. What do you
230 do? App::Rad to the rescue!
231
232 In the one-liner above, just switch 'perl' to 'myapp.pl include
233 SUBNAME' and remove the trailing parameters (somesheet.csv):
234
235 $ myapp.pl include addcsvcol -i -paF, -le 'splice @F,1,0,$.; $_=join ",",@F'
236
237 That's it! Now myapp.pl has the 'addcsvcol' command (granted, not the
238 best name) and you can call it directly whenever you want:
239
240 $ myapp.pl addcsvcol somesheet.csv
241
242 App::Rad not only transforms and adjusts your one-liner so it can be
243 used inside your program, but also automatically formats it with
244 Perl::Tidy (if you have it). This is what the one-liner above would
245 look like inside your program:
246
247 sub addcsvcol {
248 my $c = shift;
249
250 local ($^I) = "";
251 local ($/) = "\n";
252 local ($\) = "\n";
253 LINE: while ( defined( $_ = <ARGV> ) ) {
254 chomp $_;
255 our (@F) = split( /,/, $_, 0 );
256 splice @F, 1, 0, $.;
257 $_ = join( ',', @F );
258 }
259 continue {
260 die "-p destination: $!\n" unless print $_;
261 }
262 }
263
264 With so many arguments (-i, -p, -a -F,, -l -e), this is about as bad as
265 it gets. And still one might find this way easier to document and
266 mantain than a crude one-liner stored in your ~/.bash_history or
267 similar.
268
269 Note: If you don't supply a name for your command, App::Rad will make
270 one up for you (cmd1, cmd2, ...). But don't do that, as you'll have a
271 hard time figuring out what that specific command does.
272
273 Another Note: App::Rad tries to adjust the command to its interface,
274 but please keep in mind this module is still in its early stages so
275 it's not guaranteed to work every time. *PLEASE* let me know via email
276 or RT bug request if your one-liner was not correctly translated into
277 an App::Rad command. Thanks!
278
279 exclude command_name
280 Removes the requested function from your program. Note that this will
281 delete the actual code from your program, so be *extra* careful. It is
282 strongly recommended that you do not use this command and either remove
283 the subroutine yourself or add the function to your excluded list
284 inside setup().
285
286 Note that built-in commands such as 'help' cannot be removed via
287 exclude. They have to be added to your excluded list inside setup().
288
290 Creating a new command is as easy as writing any sub inside your
291 program. Some names ("setup", "default", "invalid", "pre_process",
292 "post_process" and "teardown") are reserved for special purposes (see
293 the Control Functions section of this document). App::Rad provides a
294 nice interface for reading command line input and writing formatted
295 output:
296
297 The Controller
298 Every command (sub) you create receives the controller object "$c"
299 (sometimes referred as "$self" in other projects) as an argument. The
300 controller is the main interface to App::Rad and has several methods to
301 easen your command manipulation and execution tasks.
302
303 Reading arguments
304 When someone types in a command, she may pass some arguments to it.
305 Those arguments can be accessed in four different ways, depending on
306 what you want. This way it's up to you to control which and how many
307 arguments (if at all) you want to receive and/or use. They are:
308
309 @ARGV
310
311 Perl's @ARGV array has all the arguments passed to your command,
312 without the command name (use "$c->cmd" for this) and without any
313 processing (even if you explicitly use "$c->getopt", which will change
314 $c->argv instead, see below). Since the command itself won't be in the
315 @ARGV parameters, you can use it in each command as if they were stand-
316 alone programs.
317
318 $c->options
319
320 App::Rad lets you automatically retrieve any POSIX syntax command line
321 options (getopt-style) passed to your command via the $c->options
322 method. This method returns a hash reference with keys as given
323 parameters and values as... well... values. The 'options' method
324 automatically supports two simple argument structures:
325
326 Extended (long) option. Translates "--parameter or --parameter=value"
327 into "$c->options->{parameter}". If no value is supplied, it will be
328 set to 1.
329
330 Single-letter option. Translates "-p" into "$c->options->{p}".
331
332 Single-letter options can be nested together, so "-abc" will be parsed
333 into "$c->options->{a}", "$c->options->{b}" and "$c->options{c}", while
334 "--abc" will be parsed into "$c->options->{abc}". We could, for
335 instance, create a dice-rolling command like this:
336
337 sub roll {
338 my $c = shift;
339
340 my $value = 0;
341 for ( 1..$c->options->{'times'} ) {
342 $value += ( int(rand ($c->options->{'faces'}) + 1));
343 }
344 return $value;
345 }
346
347 And now you can call your 'roll' command like:
348
349 [user@host]$ ./myapp.pl roll --faces=6 --times=2
350
351 Note that App::Rad does not control which arguments can or cannot be
352 passed: they are all parsed into "$c->options" and it's up to you to
353 use whichever you want. For a more advanced use and control, see the
354 "$c->getopt" method below.
355
356 Also note that single-letter options will be set to 1. However, if a
357 user types them more than once, the value will be incremented
358 accordingly. For example, if a user calls your program like so:
359
360 [user@host]$ ./myapp.pl some_command -vvv
361
362 or
363
364 [user@host]$ ./myapp.pl some_command -v -v -v
365
366 then, in both cases, "$c->options->{v}" will be set to 3. This will let
367 you easily keep track of how many times any given option was chosen,
368 and still let you just check for definedness if you don't care about
369 that.
370
371 $c->argv
372
373 The array reference "$c->argv" contains every argument passed to your
374 command that have not been parsed into "$c->options". This is usually a
375 list of every provided argument that didn't start with a dash (-),
376 unless you've called "$c->getopt" and used something like 'param=s'
377 (again, see below).
378
379 $c->getopt (Advanced Getopt usage)
380
381 App::Rad is also smoothly integrated with Getopt::Long, so you can have
382 even more flexibility and power while parsing your command's arguments,
383 such as aliases and types. Call the "$c->getopt()" method anytime
384 inside your commands (or just once in your "pre_process" function to
385 always have the same interface) passing a simple array with your
386 options, and refer back to $c->options to see them. For instance:
387
388 sub roll {
389 my $c = shift;
390
391 $c->getopt( 'faces|f=i', 'times|t=i' )
392 or $c->execute('usage') and return undef;
393
394 # and now you have $c->options->{'faces'}
395 # and $c->options->{'times'} just like above.
396 }
397
398 This becomes very handy for complex or feature-rich commands. Please
399 refer to the Getopt::Long module for more usage examples.
400
401 So, in order to manipulate and use any arguments, remember:
402
403 • The given command name does not appear in the argument list;
404
405 • All given arguments are in @ARGV
406
407 • Automatically processed arguments are in "$c->options"
408
409 • Non-processed arguments (the ones "$c->options" didn't catch) are
410 in $c->argv
411
412 • You can use "$c->getopt" to have "Getopt::Long" parse your
413 arguments (it will not change @ARGV)
414
415 Sharing Data: "$c->stash"
416 The "stash" is a universal hash for storing data among your Commands:
417
418 $c->stash->{foo} = 'bar';
419 $c->stash->{herculoids} = [ qw(igoo tundro zok gloop gleep) ];
420 $c->stash->{application} = { name => 'My Application' };
421
422 You can use it for more granularity and control over your program. For
423 instance, you can email the output of a command if (and only if)
424 something happened:
425
426 sub command {
427 my $c = shift;
428 my $ret = do_something();
429
430 if ( $ret =~ /critical error/ ) {
431 $c->stash->{mail} = 1;
432 }
433 return $ret;
434 }
435
436 sub post_process {
437 my $c = shift;
438
439 if ( $c->stash->{mail} ) {
440 # send email alert...
441 }
442 else {
443 print $c->output . "\n";
444 }
445 }
446
447 Returning output
448 Once you're through, return whatever you want to give as output for
449 your command:
450
451 my $ret = "Here's the list: ";
452 $ret .= join ', ', 1..5;
453 return $ret;
454
455 # this prints "Here's the list: 1, 2, 3, 4, 5"
456
457 App::Rad lets you post-process the returned value of every command, so
458 refrain from printing to STDOUT directly whenever possible as it will
459 give much more power to your programs. See the post_process() control
460 function further below in this document.
461
463 App::Rad's controller comes with several methods to help you manage
464 your application easily. If you can think of any other useful command
465 that is not here, please drop me a line or RT request.
466
467 $c->execute( COMMAND_NAME )
468 Runs the given command. If no command is given, runs the one stored in
469 "$c->cmd". If the command does not exist, the 'default' command is ran
470 instead. Each execute() call also invokes pre_process and post_process,
471 so you can easily manipulate income and outcome of every command.
472
473 $c->cmd
474 Returns a string containing the name of the command (that is, the first
475 argument of your program), that will be called right after pre_process.
476
477 $c->command
478
479 Alias for "$c->cmd". This longer form is discouraged and may be removed
480 in future versions, as one may confuse it with the "$c->commands()"
481 method, explained below. You have been warned.
482
483 $c->commands()
484 Returns a list of available commands (functions) inside your program
485
486 $c->is_command ( COMMAND_NAME )
487 Returns 1 (true) if the given COMMAND_NAME is available, 0 (false)
488 otherwise.
489
490 $c->create_command_name()
491 Returns a valid name for a command (i.e. a name slot that's not been
492 used by your program). This goes in the form of 'cmd1', 'cmd2', etc.,
493 so don't use unless you absolutely have to. App::Rad, for instance,
494 uses this whenever you try to include (see below) a new command but do
495 not supply a name for it.
496
497 $c->load_config( FILE (FILE2, FILE3, ...) )
498 This method lets you easily load into your program one or more
499 configuration files written like this:
500
501 # comments and blank lines are discarded
502 key1 value1
503 key2:value2
504 key3=value3
505 key5 # stand-alone attribute (and inline-comment)
506
507 $c->config
508 Returns a hash reference with any loaded config values (see
509 "$c->load_config()" above).
510
511 $c->register ( NAME, CODEREF [, INLINE_HELP ])
512 Registers a coderef as a callable command. Note that you don't have to
513 call this in order to register a sub inside your program as a command,
514 run() will already do this for you - and if you don't want some
515 subroutines to be issued as commands you can always use
516 "$c->register_commands()" (note the plural) inside setup(). This is
517 just an interface to dinamically include commands in your programs. The
518 function returns the command name in case of success, undef otherwise.
519
520 It is also very useful for creating aliases for your commands:
521
522 sub setup {
523 my $c = shift;
524 $c->register_commands();
525
526 $c->register('myalias', \&command);
527 }
528
529 sub command { return "Hi!" }
530
531 and, on the command line:
532
533 [user@host]$ ./myapp.pl command
534 Hi!
535
536 [user@host]@ ./myapp.pl myalias
537 Hi!
538
539 The last parameter is optional and lets you add inline help to your
540 command:
541
542 $c->register('cmd_name', \&cmd_func, 'display secret of life');
543
544 $c->register_command ( NAME, CODEREF [, INLINE_HELP ] )
545
546 Longer alias for "$c->register()". It's use is disencouraged as one may
547 confuse it with "register_commands" (note the plural) below. Plus you
548 type more :) As such, this method may be removed in future versions.
549 You have been warned!
550
551 $c->register_commands()
552 This method, usually called during setup(), tells App::Rad to register
553 subroutines as valid commands. If called without any parameters, it
554 will register all subroutines in your main program as valid commands
555 (note that the default behavior of App::Rad is to ignore subroutines
556 starting with an underscore '_'). You can easily change this behavior
557 using some of the options below:
558
559 Adding single commands
560
561 $c->register_commands( qw/foo bar baz/ );
562
563 The code above will register only the subs "foo", "bar" and "baz" as
564 commands. Other subroutines will not be valid commands, so they can be
565 used as internal subs for your program. You can change this behavior
566 with the bundled options - see 'Adding several commands' and 'Putting
567 it all together' below.
568
569 Adding single commands (with inline help)
570
571 $c->register_commands(
572 {
573 dos2unix => 'convert text files from DOS to Unix format',
574 unix2dos => 'convert text files from Unix to DOS format',
575 }
576 );
577
578 You can pass a hash reference containing commands as keys and a small
579 help string as their values. The code above will register only the subs
580 "dos2unix" and "unix2dos", and the default help for your program will
581 become something like this:
582
583 [user@host]$ ./myapp.pl
584 Usage: myapp.pl command [arguments]
585
586 Available Commands:
587 dos2unix convert text files from DOS to Unix format
588 help show syntax and available commands
589 unix2dos convert text files from Unix to DOS format
590
591 Adding several commands
592
593 You can pass a hash reference as an argument, letting you choose which
594 subroutines to add as commands. The following keys may be used (note
595 the dash preceding each key):
596
597 • "-ignore_prefix": subroutine names starting with the given string
598 won't be added as commands
599
600 • "-ignore_suffix": subroutine names ending with the given string
601 won't be added as commands
602
603 • "-ignore_regexp": subroutine names matching the given regular
604 expression (as a string) won't be added as commands
605
606 For example:
607
608 use App::Rad;
609 App::Rad->run();
610
611 sub setup {
612 my $c = shift;
613 $c->register_commands( { -ignore_prefix => '_' } );
614 }
615
616 sub foo {} # will become a command
617 sub bar {} # will become a command
618 sub _baz {} # will *NOT* become a command
619
620 This way you can easily segregate between commands and helper
621 functions, making your code even more reusable without jeopardizing the
622 command line interface (As of version 1.04, ignoring commands with
623 underscore '_' prefixes is also the default App::Rad behavior).
624
625 Putting it all together
626
627 You can combine some of the options above to have even more
628 flexibility:
629
630 $c->register_commands(
631 'foo',
632 { -ignore_suffix => 'foo' },
633 { bar => 'all your command line are belong to us' },
634 );
635
636 The code above will register as commands all subs with names not ending
637 in 'foo', but it will register the 'foo' sub as well. It will also give
638 the 'bar' command the help string. This behavior is handy for
639 registering several commands and having a few exceptions, or to add
640 your commands and only have inline help for a few of them (as you see
641 fit).
642
643 You don't have to worry about the order of your elements passed,
644 App::Rad will figure them out for you in a DWIM fashion.
645
646 # this does the same as the code above
647 $c->register_commands(
648 { bar => 'all your command line are belong to us' },
649 'foo',
650 { -ignore_suffix => 'foo' },
651 );
652
653 You can even bundle the hash reference to include your "cmd => help"
654 and special keys:
655
656 # this behaves the same way as the code above:
657 $c->register_commands(
658 'foo',
659 {
660 -ignore_suffix => 'foo',
661 bar => 'all your command line are belong to us',
662 }
663 );
664
665 $c->unregister_command ( NAME )
666 Longer alias for "$c->unregister()". The use of the shorter form is
667 encouraged, and this alias may be removed in future versions. You have
668 been warned.
669
670 $c->unregister ( NAME )
671
672 Unregisters a given command name so it's not available anymore. Note
673 that the subroutine will still be there to be called from inside your
674 program - it just won't be accessible via command line anymore.
675
676 $c->debug( MESSAGE )
677 Will print the given message on screen only if the debug flag is
678 enabled:
679
680 use App::Rad qw( debug );
681
682 Note that, if debug is enabled, App::Rad itself will print several
683 debug messages stating its current flow, so you can easily find out
684 where everything is happening.
685
686 $c->plugins()
687 Returns a list of all loaded plugins, in the order in which they were
688 loaded.
689
690 $c->load_plugin( PLUGIN NAME )
691 This method will dinamically load the given plugin. The plugin needs to
692 be under the "App::Rad::Plugin" namespace, and the name should be
693 relative to this path (i.e. $c->load_plugin('MyPlugin') will try to
694 load 'App::Rad::Plugin::MyPlugin'). If you want to load a plugin by its
695 fully qualified name, you need to prepend a plus sign to the name
696 ('+Fully::Qualified::Plugin::Name'). This is an internal method and you
697 really should refrain from using it. Instead, plugins should be loaded
698 as parameters to the "use App::Rad" statement, as explained above.
699
701 App::Rad implements some control functions which are expected to be
702 overridden by implementing them in your program. They are as follows:
703
704 setup()
705 This function is responsible for setting up what your program can and
706 cannot do, plus everything you need to set before actually running any
707 command (connecting to a database or host, check and validate things,
708 download a document, whatever). Note that, if you override setup(), you
709 *must* call "$c->register_commands()" or at least "$c->register()" so
710 your subs are classified as valid commands (check
711 $c->register_commands() above for more information).
712
713 Another interesting thing you can do with setup is to manipulate the
714 command list. For instance, you may want to be able to use the
715 "include" and "exclude" commands, but not let them available for all
716 users. So instead of writing:
717
718 use App::Rad qw(include exclude);
719 App::Rad->run();
720
721 you can write something like this:
722
723 use App::Rad;
724 App::Rad->run();
725
726 sub setup {
727 my $c = shift;
728 $c->register_commands();
729
730 # EUID is 'root'
731 if ( $> == 0 ) {
732 $c->register('include', \&App::Rad::include);
733 $c->register('exclude', \&App::Rad::exclude);
734 }
735 }
736
737 to get something like this:
738
739 [user@host]$ myapp.pl help
740 Usage: myapp.pl command [arguments]
741
742 Available Commands:
743 help
744
745 [user@host]$ sudo myapp.pl help
746 Usage: myapp.pl command [arguments]
747
748 Available Commands:
749 exclude
750 help
751 include
752
753 default()
754 If no command is given to your application, it will fall in here.
755 Please note that invalid (non-existant) command will fall here too, but
756 you can change this behavior with the invalid() function below
757 (although usually you don't want to).
758
759 Default's default (grin) is just an alias for the help command.
760
761 sub default {
762 my $c = shift;
763
764 # will fall here if the given
765 # command isn't valid.
766 }
767
768 You are free (and encouraged) to change the default behavior to
769 whatever you want. This is rather useful for when your program will
770 only do one thing, and as such it receives only parameters instead of
771 command names. In those cases, use the "default()" sub as your main
772 program's sub and parse the parameters with "$c->argv" and "$c->getopt"
773 as you would in any other command.
774
775 invalid()
776 This is a special function to provide even more flexibility while
777 creating your command line applications. This is called when the user
778 requests a command that does not exist. The built-in invalid() will
779 simply redirect itself to default() (see above), so usually you just
780 have to worry about this when you want to differentiate between "no
781 command given" (with or without getopt-like arguments) and "invalid
782 command given" (with or without getopt-like arguments).
783
784 teardown()
785 If implemented, this function is called automatically after your
786 application runs. It can be used to clean up after your operations,
787 removing temporary files, disconnecting a database connection
788 established in the setup function, logging, sending data over a
789 network, or even storing state information via Storable or whatever.
790
791 pre_process()
792 If implemented, this function is called automatically right before the
793 actual wanted command is called. This way you have an optional pre-run
794 hook, which permits functionality to be added, such as preventing some
795 commands to be run from a specific uid (e.g. root):
796
797 sub pre_process {
798 my $c = shift;
799
800 if ( $c->cmd eq 'some_command' and $> != 0 ) {
801 $c->cmd = 'default'; # or some standard error message
802 }
803 }
804
805 post_process()
806 If implemented, this function is called automatically right after the
807 requested function returned. It receives the Controller object right
808 after a given command has been executed (and hopefully with some output
809 returned), so you can manipulate it at will. In fact, the default
810 "post_process" function is as goes:
811
812 sub post_process {
813 my $c = shift;
814
815 if ( $c->output() ) {
816 print $c->output() . "\n";
817 }
818 }
819
820 You can override this function to include a default header/footer for
821 your programs (either a label or perhaps a "Content-type: " string),
822 parse the output in any ways you see fit (CPAN is your friend, as
823 usual), etc.
824
826 The post_process() function above is why your application should
827 *NEVER* print to STDOUT. Using print (or say, in 5.10) to send output
828 to STDOUT is exclusively the domain of the post_process() function.
829 Breaking this rule is a common source of errors. If you want your
830 functions to be interactive (for instance) and print everything
831 themselves, you should disable post-processing in setup(), or create an
832 empty post_process function or make your functions return undef (so
833 post_process() will only add a blank line to the output).
834
836 If you see a '1' printed on the screen after a command is issued, it's
837 probably because that command is returning a "true" value instead of an
838 output string. If you don't want to return the command output for post
839 processing(you'll loose some nice features, though) you can return
840 undef or make post_process() empty.
841
843 App::Rad requires no configuration files or environment variables.
844
846 App::Rad depends only on 5.8 core modules (Carp for errors,
847 Getopt::Long for "$c->getopt", Attribute::Handlers for "help" and
848 O/B::Deparse for the "include" command).
849
850 If you have Perl::Tidy installed, the "include" command will tidy up
851 your code before inclusion.
852
853 The test suite depends on Test::More, FindBin and File::Temp, also core
854 modules.
855
857 None reported.
858
860 Please report any bugs or feature requests to "bug-app-easy at
861 rt.cpan.org", or through the web interface at
862 <http://rt.cpan.org/garu/ReportBug.html?Queue=App-Rad>. I will be
863 notified, and then you'll automatically be notified of progress on your
864 bug as I make changes.
865
867 You can find documentation for this module with the perldoc command.
868
869 perldoc App::Rad
870
871 Although this Module comes without any warraties whatsoever (see
872 DISCLAIMER below), I try really hard to provide some quality assurance
873 for the users. This means I not only try to close all reported bugs in
874 the minimum amount of time but I also try to find some on my own.
875
876 This version of App::Rad comes with 183 tests and I keep my eye
877 constantly on CPAN Testers
878 <http://www.cpantesters.org/show/App-Rad.html> to ensure it passes all
879 of them, in all platforms. You can send me your own App::Rad tests if
880 you feel I'm missing something and I'll hapilly add them to the
881 distribution.
882
883 Since I take user's feedback very seriously, I really hope you send me
884 any wishlist/TODO you'd like App::Rad to have (please try to send them
885 via RT so other people can give their own suggestions).
886
887 You can also look for information at:
888
889 • RT: CPAN's request tracker
890
891 <http://rt.cpan.org/garu/Bugs.html?Dist=App-Rad>
892
893 • AnnoCPAN: Annotated CPAN documentation
894
895 <http://annocpan.org/dist/App-Rad>
896
897 • CPAN Ratings
898
899 <http://cpanratings.perl.org/d/App-Rad>
900
901 • Search CPAN
902
903 <http://search.cpan.org/dist/App-Rad>
904
905 IRC
906 #app-rad on irc.perl.org
907
909 This is a small list of features I plan to add in the near future (in
910 no particular order). Feel free to contribute with your wishlist and
911 comentaries!
912
913 • Shell-like environment
914
915 • Loadable commands (in an external container file)
916
917 • Modularized commands (similar to App::Cmd::Commands ?)
918
919 • app-starter
920
921 • command inclusion by prefix, suffix and regexp (feature request by
922 fco)
923
924 • command inclusion and exclusion also by attributes
925
926 • some extra integration, maybe IPC::Cmd and IO::Prompt
927
929 Breno G. de Oliveira, "<garu at cpan.org>"
930
932 (in alphabetical order)
933
934 Ben Hengst
935
936 Fernando Correa
937
938 Flavio Glock
939
940 Thanks to everyone for contributing! Please let me know if I've skipped
941 your name by accident.
942
944 This module was inspired by Kenichi Ishigaki's presentation "Web is not
945 the only one that requires frameworks" during YAPC::Asia::2008 and the
946 modules it exposed (mainly App::Cmd and App::CLI).
947
948 Also, many thanks to CGI::App(now Titanium)'s Mark Stosberg and all the
949 Catalyst developers, as some of App::Rad's functionality was taken from
950 those (web) frameworks.
951
953 Copyright 2008 Breno G. de Oliveira "<garu at cpan.org>". All rights
954 reserved.
955
956 This module is free software; you can redistribute it and/or modify it
957 under the same terms as Perl itself. See perlartistic.
958
960 BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
961 FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
962 WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
963 PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
964 EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
965 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
966 ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
967 YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
968 NECESSARY SERVICING, REPAIR, OR CORRECTION.
969
970 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
971 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
972 REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
973 TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
974 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
975 SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
976 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
977 FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
978 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
979 DAMAGES.
980
981
982
983perl v5.38.0 2023-07-20 App::Rad(3)