# In myscript.cgi, or your mod_perl configuration, or wherever: # This could be relative to the script path or config file my $plugin_dir = '/opt/myscript/plugins'; sub load_plugins { # Read in the names of all .pm or .pl files in the plugins dir. # (Even better would be a recursive search of subdirectories.) unless ( opendir(PLUGINDIR, $plugin_dir) { warn "Plugin dir '$plugin_dir' is missing or unreadable."; return; } my @filenames = grep /\.p[ml]/, readdir(PLUGINDIR); closedir(PLUGINDIR); # Put the plugins directory in our library search path. # This allows one plugin to use or require another one. local @INC = ( $plugin_dir, @INC ); # Try to load all of the plugin files, but don't die trying. foreach my $plugin ( sort @filenames ) { eval "require $plugin"; if ( $@ ) { warn "Skipping plugin $plugin: $@" } } } sub print_output { print @_; } load_plugins(); print_output( "Here's my CGI script output." ); #### # In $plugins_dir/uppercase.pm: sub print_output { print map { uc } @_; } #### # In $plugins_dir/uppercase.pm: my $inner_print_output; BEGIN { $inner_print_output = \&print_output } sub print_output { &$inner_print_output( map { uc } @_ ); } #### # In $plugins_dir/remove_whitespace.pm: my $inner_print_output; BEGIN { $inner_print_output = \&print_output } sub print_output { &$inner_print_output( map { s/\s//g } @_ ); }