When I had more time I started a project which needed lots of modularity. Nearly all features would be optional, so every part of the program was designed as a plugin.

The only "core" was the definition of the data plugins knew about, the MVC-esque "model" of the program.

The program was then (in theory) reincarnated many times into byte sized scripts, that, for example, load the plugin-loader-plugin, which assumes plugins are Module::Pluggable like in their format, and then loads them up.

The system I wrote to back this up was centered around totum-pole objects. The instances of the plugin objects were joined into one object, which pretended to be all those objects at the same time. Each plugin had it's own private space, it's own instance, and there was a clear api letting you talk to other plugins.

The general design was that a plugin was either a sort of care taker for a certain group of plugins, which is responsible for arranging for proper dispatch of a method, or something having to do with how simple plugins work together, or it is a plugin that provided functionality, and is arranged by some other plugin.

To pipeline an operation, for example, you need about 5 lines of code in a caretaker plugin, simple filter like plugins which get and return much of the same data. To do type or capability based dispatch, for example, to make the method "ring" work on both bells and piano forks, you define some sort of protocol, to find out which plugin likes what:

package Plugin; ... sub process { my $self = shift; my $foo = shift; $foo->FooMethod(); ... } sub processes { return qw/Foo/; # this module's process method likes objects which + isa Foo. }
and then the "caretaker" will have a plugin search order, and the first plugin that processes our object, gets it:
sub process { my $self = shift; my $obj = shift; my @args = @_; DISPATCH: foreach my $plugin ($self->host->stack("process") { # th +e stack of plugins that ->process foreach my $class ($plugin->processes){ next unless $obj->isa($class); return $self->host->specific($plugin)->process($obj, $args +); } } }
For such an idiom I'd probably implement a
package Plugin; sub process : expects(FooClass) { my $self = shift; my $foo = shift; }
With the "caretaker" reading the attrs for the method. However, since I have no time to work on that project anymore, it's not being actively used.

Anyway, without further ado, I give you Object::Meta::Plugin.

-nuffin
zz zZ Z Z #!perl

In reply to Re: Plugin Programming by nothingmuch
in thread Plugin Programming by theirpuppet

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.