App-Easer
view release on metacpan or search on metacpan
docs/docs/30-commands-hierarchy.md view on Meta::CPAN
},
foo => {
'no-auto' => '*',
...
},
bar => {
'no-auto' => ['help'],
...
}
},
};
```
In this example:
- the only automatically added child command is `help` (via option
`auto-children`);
- the `MAIN` command gets the `commands` sub-command too, although
explicitly and not implicitly;
- the `foo` command gets nothing, because `no-auto` filters out *every*
implicitly generated sub-command;
- the `bar` command gets nothing as well, because its `no-auto` filters
out the `help` command, which is also the only one that is set.
## Specification from module
By default, all specifications for (sub-)commands are supposed to be
contained in the input hash/JSON specification for the whole
application. It is possible, though, to put the specification of one or
more sub-commands inside a different module, to keep the specification
and the implementation close to each other, setting the configuration
`specfetch` to `+SpecFromHashOrModule`:
```perl
my $app = {
configuration => { specfetch => '+SpecFromHashOrModule' },
commands => {
MAIN => {
children => [qw< MyApp::Foo MyApp::Bar#specification baz >],
...
},
baz => { ... },
}
};
```
In the example above:
- commands `MAIN` and `baz` are defined directly in the hash, like it
happens by default;
- the definition for sub-command `MyApp::Foo` can be found in module
`MyApp::Foo`, calling its function `spec` that is supposed to return a
hash reference with the specification of the command. The name `spec`
is a default, conventional value;
- the definition for sub-command `MyApp::Bar#specification` can be found
in module `MyApp::Bar`, calling its function `specification`. In this
case we have an explicit indication of which function should be called
to get the hash reference with the sub-command specification.
When `specfetch` is set to `+SpecFromHashOrModule`, the child name is
expanded as described above only if the specific string is missing as a
key inside the `commands` sub hash. In other terms, in the following
example no external module will be loaded to figure out the
specification for child `Some::Foo#whatever`, because the specification
is already available in `commands`:
```perl
my $app = {
configuration => { specfetch => '+SpecFromHashOrModule' },
commands => {
MAIN => {
children => [qw< Some::Foo#whatever >],
...
},
'Some::Foo#whatever' => { ... },
}
};
```
It might be even adviseable to use this name structure, actually: it
allows starting with a compact application definition, while allowing
for an easy split at a later time if this is the main goal.
## Dispatch: vague relationships
[App::Easer][] supports providing an *executable* associated to key
`dispatch`, in order to completely override the child search mechanism:
```perl
my $app = {
commands => {
MAIN => {
children => [qw< foo bar baz >],
dispatch => \&random_child,
...
},
foo => { ... },
bar => { ... },
baz => { ... },
},
};
# ...
sub random_child ($app, $spec, $args) {
my @children = $spec->{chidren}->@*;
return $children[rand @children];
}
```
The example above is a bit crude but shows that the
`dispatch`-associated function is supposed to return the name of a
command. The example uses `children` to choose from, but it can actually
be any valid command:
```perl
my $app = {
commands => {
MAIN => {
children => [qw< bar baz >],
dispatch => sub { return 'foo' }, # not a child, but OK!
( run in 1.467 second using v1.01-cache-2.11-cpan-97f6503c9c8 )