Subject: | Would like a lazy require option. |
I've been using App::Cmd as a framework for defining individual batch
jobs. This has worked out fairly well so far, but as the number of
jobs/commands has increased into the 70+ range, the overhead of doing a
C<require> on each command has become noticeable.
Because these jobs do a wide range of tasks, each call to the main app
ends up loading 600-ish pm files.
Would you consider adding a C<lazy_load> option which, when true, would
only C<require> the given command during the C<_prepare_command> phase?
Using this option would necessarily enforce a 1-command-per-pm limit.
An added benefit to this in a shared environment, is that other users'
broken commands only affect you if you attempt a command listing or help.
I've attached a proof of concept patch. If you are interested in adding
this option I could create a more formal patch with tests.
Thanks,
- danboo
Subject: | app-cmd-lazy_load.diff.txt |
--- rjbs-app-cmd-bbcbce1/lib/App/Cmd.pm 2009-12-07 18:53:17.000000000 -0500
+++ app-cmd-patch/lib/App/Cmd.pm 2010-02-24 13:13:03.705379000 -0500
@@ -168,13 +168,20 @@
my %plugin;
for my $plugin ($self->_plugins) {
- eval "require $plugin" or die "couldn't load $plugin: $@"
- unless eval { $plugin->isa( $self->_default_command_base ) };
- next unless $plugin->can("command_names");
- foreach my $command (map { lc } $plugin->command_names) {
- die "two plugins for command $command: $plugin and $plugin{$command}\n"
- if exists $plugin{$command};
+ if ( ! $arg->{lazy_load} ) {
+ eval "require $plugin" or die "couldn't load $plugin: $@"
+ unless eval { $plugin->isa( $self->_default_command_base ) };
+ next unless $plugin->can("command_names");
+ foreach my $command (map { lc } $plugin->command_names) {
+ die "two plugins for command $command: $plugin and $plugin{$command}\n"
+ if exists $plugin{$command};
+ $plugin{$command} = $plugin;
+ }
+ }
+ else {
+ my $command = $plugin;
+ $command =~ s/.*:://;
$plugin{$command} = $plugin;
}
}
@@ -327,6 +334,7 @@
sub _prepare_command {
my ($self, $command, $opt, @args) = @_;
if (my $plugin = $self->plugin_for($command)) {
+ eval "require $plugin" or die "couldn't load $plugin: $@";
return $plugin->prepare($self, @args);
} else {
return $self->_bad_command($command, $opt, @args);