Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Creating a "Plug-In" Framework for a Module

by ajt (Prior)
on Jan 30, 2006 at 13:33 UTC ( #526442=perlquestion: print w/ replies, xml ) Need Help??
ajt has asked for the wisdom of the Perl Monks concerning the following question:

Hi!

I have some old code that I want to turn into a module, see Old Templating Engine. It's very simple really the only messy bit is that there can be several different ways of doing the same thing.

Rather than create one large monolitic OO module, I'd rather create a core module and then a set of plug-ins that add the extra functionality. If a given plug-in in isn't installed then it's not an available. If two plug-ins are installed that provide the same function, then the module and the end user would get to choose which plug-in to use.

I've done some searching, but I mostly get matches from modules that are plug-ins, not how to create the framework.

Any guidance on how to create a module that will accept a family of other modules as plug-ins?

As ever thanks in advance.


--
ajt

Comment on Creating a "Plug-In" Framework for a Module
Re: Creating a "Plug-In" Framework for a Module
by Fletch (Chancellor) on Jan 30, 2006 at 13:50 UTC
Re: Creating a "Plug-In" Framework for a Module
by g0n (Priest) on Jan 30, 2006 at 14:49 UTC
    One method I've used for handling plugins (thanks to the guidance of various monks in the CB) is a delegation class - something like this:

    package Toolkit::DB; ############################################# # new - constructor # # # returns blessed db object ############################################# sub new { my $self = shift; my %params = @_; if (!$params{dbtype}) { $params{dbtype} = "Toolkit::FileDB"; } $params{delegate} = "$params{dbtype}"->new(%params); return bless \%params,$self; } ############################################# # insert - add a record to the db # # takes hash of fieldname/fieldcontent # # returns success/fail ############################################# sub insert { my $self = shift; my %data = @_; my $result = $self->{delegate}->insert(%data); return $result; }

    (With similar methods for all the other function calls needed). Then at run time you can choose which implementation class to use, or take the default ('Toolkit::FileDB' in this instance).

    Update: It's just occurred to me - that way you could also create stubs for the functionality that return 'this function is not available without X::Y::Z installed' instead of a fatal error.

    Update: There's some possibly related discussion about using use and require in Use and Require - making an informed choice.

    --------------------------------------------------------------

    "If there is such a phenomenon as absolute evil, it consists in treating another human being as a thing."

    John Brunner, "The Shockwave Rider".

Re: Creating a "Plug-In" Framework for a Module
by lachoy (Parson) on Jan 30, 2006 at 15:06 UTC
Re: Creating a "Plug-In" Framework for a Module
by jZed (Prior) on Jan 31, 2006 at 20:34 UTC
    Here's how I do it in DBI::SQL::Nano -
    BEGIN { if ($ENV{DBI_SQL_NANO} || !eval { require "SQL/Statement.pm" }) { @DBI::SQL::Nano::Statement::ISA = qw(DBI::SQL::Nano::Statement +_); @DBI::SQL::Nano::Table::ISA = qw(DBI::SQL::Nano::Table_); } else { @DBI::SQL::Nano::Statement::ISA = qw( SQL::Statement ); @DBI::SQL::Nano::Table::ISA = qw( SQL::Eval::Table); } }
    Doing it in the BEGIN block means the if statement will only be evaluated once per require. Using Environment Variables gives the flexibility of choosing alternate modules once per server, once per user, once per script, or once per script invocation. Doing the eval on the require allows for a default mode if one of the alternatives is not available in a given context.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://526442]
Approved by wfsp
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (9)
As of 2014-07-11 02:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (217 votes), past polls