Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the App-Cmd CPAN distribution.

Report information
The Basics
Id: 54947
Status: resolved
Priority: 0/
Queue: App-Cmd

People
Owner: Nobody in particular
Requestors: danboo [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.304
Fixed in: (no value)



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);