Okay, here's a new approach to callbacks that solves the same issues,
but doesn't require a Plugin base class.
Basically, I changed the callback mechanism from object-based to class-
based. Instead of storing hooks and callbacks in $self->{__HOOKS},
hooks are now stored in the hash %INSTALLED_HOOKS.
However, the each callback is keyed by a particular class; only
callbacks installed by plugins related to the current application are
ever run.
A plugin can create hooks and add callbacks at any time - even before
the $self object has been initialized. A good place to do this is in
the import subroutine:
sub import {
CGI::Application->add_callback('init', 'my_setup', 'FIRST', scalar(caller));
goto &Exporter::import;
}
When CGI::Application installs the callback, it records the class of the
module that used the plugin (hence the "scalar(caller)" parameter).
When the callbacks for a particular hook are triggered, CGI::Application
runs all callbacks installed by plugins that were used by $self or
by superclasses of $self.
It skips callbacks installed by plugins that are used by modules
unrelated to $self.
In a persistent environment, there might be a lot of applications
in memory at the same time. For instance:
CGI::Application
Other::Project # uses CGI::Application::Plugin::Baz
Other::App # uses CGI::Application::Plugin::Bam
My::Project # uses CGI::Application::Plugin::Foo
My::App # uses CGI::Application::Plugin::Bar
When My::App runs, only the callbacks installed by the following plugins
will run:
CGI::Application::Plugin::Foo
CGI::Application::Plugin::Bar
The other callbacks are skipped.
I have also changed the position scheme. Instead of limiting the
positions to 'REALLY_FIRST', 'FIRST', 'MIDDLE', 'LAST', and
'REALLY_LAST', you can now specify a numeric position between 0 and 100.
The named positions are still available, but they are aliases for
numeric positions:
REALLY_FIRST => 5
FIRST => 15
MIDDLE => 50
DONTCARE => 50
LAST => 85
REALLY_LAST => 95
So, the following two calls are equivalent:
CGI::Application->add_callback('teardown', 'my_fixup', 'LAST', scalar(caller));
CGI::Application->add_callback('teardown', 'my_fixup', 85, scalar(caller));
This gives plugin authors some flexibility in the ordering of their
callbacks.
I've made a tarball available here:
http://www.occamstoothbrush.com/downloads/perl/CGI-Application-4.0_2-class-callbacks-patch.tgz
The example script is called 'test-class-callbacks.pl'.
Michael
-----------------------------------------------------------------------
Michael Graham <suppressed>
YAPC::NA 2005 Toronto - http://www.yapc.org/America/ - suppressed
-----------------------------------------------------------------------
---------------------------------------------------------------------
Web Archive: http://www.mail-archive.com/suppressed/
http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: suppressed
For additional commands, e-mail: suppressed
Mail converted by mhonarc 2.6.15
This archive provided courtesy of JSW4.NET, Internet Hosting Services for Small Business.