App-Easer
view release on metacpan or search on metacpan
docs/docs/15-tutorial-splitting.md view on Meta::CPAN
```
For simplicity, we're exporting *all* subs.
## Moving a command, basic
Let's start taking a look at the command modules, beginning with the one
for the `done` sub-command:
```perl
package MuDu::Command::Done;
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
use MuDu::Utils;
sub spec {
return {
help => 'mark a task as completed',
description => 'Archive a task as completed',
supports => [qw< done tick yay >],
execute => \&execute,
}
}
sub execute ($m, $config, $args) { move_task($config, $args, 'done') }
1;
```
It's basically taking the command specification from the old global
hash, and putting it inside the `spec` function. The implementation in
`execute` is then linked directly, by taking a reference to it.
## Need a different style?
People used to other systems might prefer to have a different functions
for the different attributes inside the specification hash, like having
a sub for `help`, one for `description`, etc.
This can be easily accomplished by using a small helper function, put in
`MuDu::Utils` so that's automatically imported:
```perl
sub autospec ($package, %direct) {
for my $key (qw< description help options supports >) {
next if exists $direct{$key};
my $sub = $package->can($key) or next;
$direct{$key} = $sub->();
}
$direct{execute} //= $package;
return \%direct;
}
```
The `execute` key is (conditionally) set to the package name. When
provided with a package name, the resolution process in [App::Easer][]
looks for a sub called `execute` inside that package, so it will suffice
to call our command implementation `sub execute`.
The specific way `autospec` is implemented (i.e. accepting an input hash
`%direct`) allows us to adopt different degrees of shifting stuff from
the hash to the functions. As an example, we go full-on with the
implementation for sub-command `add`:
```perl
package MuDu::Command::Add;
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
use POSIX 'strftime';
use MuDu::Utils;
sub spec { __PACKAGE__->autospec() }
sub help { return 'add a task' }
sub description { return 'Add a task, optionally setting it as waiting' }
sub supports { return [qw< add new post >] }
sub options {
return [
{
help => 'add the tasks as waiting',
getopt => 'waiting|w!'
},
{
help => 'set the editor for adding the task, if needed',
getopt => 'editor|visual|e=s',
environment => 'VISUAL',
default => 'vi',
}
];
}
sub execute ($main, $config, $args) {
my $id = strftime('%Y%m%d-%H%M%S', localtime);
my $category = $config->{waiting} ? 'waiting' : 'ongoing';
my $hint = path($config->{basedir})->child($category, $id);
my $target = add_file($config, $hint, '');
if ($args->@*) {
$target->spew_utf8(join(' ', $args->@*) . "\n");
return 0;
}
return 0 if edit_file($config, $target) && length get_title($target);
$target->remove if -e $target;
fatal("bailing out creating new task");
}
1;
```
As we can see, the `spec` function is implemented to call `autospec`,
this time only passing the `__PACKAGE__` name as the first parameter.
In sub-command `cat`, instead, we can opt for a midway and partially use
the hash input parameter for `autospec` and part the functions:
```perl
package MuDu::Command::Cat;
( run in 2.237 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )