これってもうCPANにあるのかな。

Plaggerみたいにプラグインで構成するライブラリが欲しいんだけど、別にアグレゲーターしたいわけじゃなくて、全然違う用途に使いたいのです。しかも、フックポイントをアプリケーション毎に変えたいから、それさえも設定ファイルに入れたいわけ。

で、ないのかと思って書いてみた。

もしよかったらコメントしてください。同等のモジュールを見落としてるだけという可能性もあるのでそれPla的なコメントでもいいので。
=head1 NAME Plugal - Generic Plugin Execution Framework =head1 SYNOPSIS use Plugal; Plugal->bootstrap('config.yaml'); Plugal->run; =head1 DESCRIPTION Plugal is a simple framework to define hooks, and run associated plugins. (If you're familiar with Plagger, think of it as Plagger without the bells an whistles for fetching feeds) =head1 USAGE Plugal is designed to read in all of its configuration from a file. Plugal->bootstrap('config.yaml'); The config file should contain at least two sections. One is to specify the hook points that Plugal witll call the plugins from: hook_points: - start - foo - bar - end These hook points can be something totally arbitrary: You get to decide in what order you want to execute things. This basically translates into: foreach my $hook_point qw(start foo bar end) { $plugal->run_hooks($hook_point); # above translates to # foreach my $hook (@hooks_at_particular_hook_point) { # execute $hook; # } } i.e., hooks associated with the named $hook_point are run in order. The hook points are now defined. You now need to define which plugins are executed at those hook points The other section you need is a plugins section. This tells Plugal which plugins to load: plugins: - module: Foo # Note: loads Plugal::Plugin::Foo args: # Note: Passed to Plugal::Plugin::Foo->new() arg1: foo arg2: bar - module: '+My::Plugin::Bar' # Note: loads My::Plugin::Bar args: # Note: Passed to My::Plugin::Bar->new() arg1: foo arg2: bar Each of these plugins should register itself, so Plugal knows when to call them. This is done in the plugin's C<register()> method. For example, package Plugal::Plugin::Foo; use base qw(Plugal::Plugin); sub register { my ($self, $c) = @_; ... whatever initialization ... $c->register_hook('start', \&coderef); $c->register_hook('foo', [ $self, 'do_foo', @args ]); } The above snippet registers plugin Plugal::Plugin::Foo so that (1) \&coderef is called at "start" hook point (2) $self->do_foo($c, @args) is called at "foo" hook point The first form is pretty straight forward. It calls a code reference at the hook point 'start' (which is defined prefivously in the "hook_point" configuration). \&coderef will receieve 2 arguments: a reference to the plugin, and a reference to the context object (the main Plugal instance). Thus, the coderef should be defined as such: package Plugal::Plugin::Foo; ... sub coderef { my ($self, $c) = @_; # do whatever } Of couse, \&coderef can be an anonymous routine, or whatever you please. The second form is slightly more complex. It allows you to specify a method call without explicitly specifying a closure. If the second argument to register_hook() is an arrayref, we expect the form: [ $object, $method_name, @extra_args ] This is then called as $object->$method_name($c, @extra_args) So your method definition should be sub method { my ($self, $c, @other_args) = @_; ... } $c is the same $c that you received in the register() method. And now you're ready. Initialize Plugal with the config as above, and then call C<run()> my $plugal = Plugal->bootstrap('config.yaml'); $plugal->run(); =head1 AUTHOR Copyright (c) 2008 Daisuke Maki E<lt>daisuke@endeworks.jpE<gt> Concepts and some code taken from Plagger. =head1 LICENSE This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut