http://qs321.pair.com?node_id=8878

guice has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing this application that's going to run as a CGI script on a FreeBSD system. I want to make it as expandable as possible ... Then it hit me, a plugin based perl application. It only has features of the plugins that I put into a select directory.

My question is quite simple. What are your all's thoughts on implementing something like this? I have a general basis on how to do this, but I thought I'd get some feedback from the Perl community and see how they would approach this.

Any thoughts?
I've thought of using a public variable (via export or use vars) that will store actions mapped to the functions that take care of them.
And A public object was passed my way. Now, I'm not tooo... sure about the implementation on this. Inheritance is not as clear in Perl as it is in C++. Or an I totally thinking the wrong direction with this idea?

Replies are listed 'Best First'.
Re: Plugin based Perl app
by chromatic (Archbishop) on Apr 25, 2000 at 08:14 UTC
    The tricky part is writing the interface. (That's what I'm working on with Jellybean right now. Another project on a more compliated kick is Iaijutsu.) A couple of tricks I'm using are references to subroutines, blessed references to subroutines, and building subroutines dynamically.

    You can bless an array with the function name, a description, and a reference to the function, and just deal with those. Assuming you provide access to things like DBI and CGI for all objects, there's no theoretical limit on what you can build.

Re: Plugin based Perl app
by perlmonkey (Hermit) on Apr 25, 2000 at 08:35 UTC
    chromatic's ideas sound pretty solid.
    The inheritance part should be pretty easy also. Just modify the @ISA array. Maybe write a generic plugin module to provide common routines. Then force the plugins to inherit from the plugin module. So in a different plugin type module do:
    use plugin; push(@ISA, "plugin");
    That way routines will be looked for first in the local package then they will be looked for in the packages named in @ISA. The plugin package might provide routines to set the subroutine references etc.
Re: Plugin based Perl app
by ZZamboni (Curate) on Apr 25, 2000 at 17:42 UTC
    Another possibility is to simply require the modules you need and let them define subroutines and such. For example, in the program from which my simple command parser comes from, the commands are loaded from a directory in which files with names starting with 2 digist and ending with ".pl" are assumed to define the appropriate subroutines and variables. Here's a simplified version of what I use to load them. Notice how I also incorporate variables declared in each module (in this case %COMMAND) into another global hash.
    # Load command modules if (-d $cmddir) { opendir(CMDDIR, $cmddir) or die "Error opening '$cmddir': $!\n"; # Get only .pl files that start with 2 digits and that contain onl +y # alphanumerics, underscores, hyphens or dots in their names. my @cmdfiles=map { (/^(\d{2}[-\w.]+\.pl)$/ && $1) || () } readdir( +CMDDIR); closedir(CMDDIR); # Read each file and incorporate its %COMMANDS into %ALLCOMMANDS my $cmdfile; if (@cmdfiles) { foreach $cmdfile (@cmdfiles) { local %COMMANDS; eval "require '$cmddir/$cmdfile'"; die "Error loading '$cmddir/$cmdfile': $!\n" if $@; my ($k,$v); # Incorporate commands while (($k,$v)=each(%COMMANDS)) { $ALLCOMMANDS{$k}=$v; } } } else { # Print warning, but continue, because builtin commands can stil +l # be used (not very useful, but...) warn "Warning: No command files found in directory '$cmddir'\n"; } } else { die "Fatal: Could not find commands dir '$cmddir'\n"; }