[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cgiapp] feedback on ::Plugin::ConfigAuto update (a use for register_hook?)



On Nov 2, 2004, at 12:04 AM, Cees Hek wrote:

On Mon, 1 Nov 2004 09:14:22 -0500, Timothy Appnel <suppressed> wrote:

* I think a means of automatically creating pre and post callback hooks
for any run mode would be a nice touch.

Can you give and example of where this would be useful?  If it is just
doing this for a single runmode, then why not put the code right in
the runmode?  If you want to do it for all runmodes, then we already
have the prerun and postrun hooks.

This goes back to an original point I made some time ago -- it depends on the purpose of callbacks.

I'm in a space (both in my head and with clients) where reuse and extensibility by others is ideal. To me the greatest advantage of callbacks is the ability for another developer to change the functionality of a base application without modify that code. Sometimes I even like to use callbacks on my own work. (Usually its when a client has some unique requirement that others likely don't share and I want to avoid a hacked up original version.) So there is the advantage of modify a single runmode without touching the code.

The possibility also remains where multiple, but not all, runmodes could make use of a callback routine. Rather then have have a series of prerun/postrun hooks be called to check if the runmode is applicable to its execution, I could have one callback method that is registered to be called by a number of different runmode hooks.

I have used Hook::Lexwrap with CGI::Application for debugging purposes
(it allows you to wrap all functions or methods with a pre and post
callback).  Actually, it was
Sub::WrapPackages that I used, but it uses Hook::Lexwrap to do the callbacks.

* The call_hook method may be better named run_callbacks,

Ya, I wouldn't have any problems changing that.

That makes it more clear in my mind since that is the method name I'm already used to calling. ;)

* I think the error handling of callbacks could be more graceful and
refined. If the callback mechanism is being used for outside
extensibility, I don't think an app should just die if an error occurs.
I'm partial to Class::ErrorHandler as a rather graceful means catching
an error and handling it in a user-friendly way.

I usually only make the code die if there is an actual mistake made in
the programming.  If a developer is calling a function with the wrong
number of parameters, then I would consider that an error and the
program should die.  If a callback that doesn't exist is added, then I
would also consider that a programming error.

Agreed, though I wish CGI::App would provide a means of catching that and displaying it to the browser rather then throwing up a 500 error and forcing a tail through the server error log.

If you can provide some code that uses a cleaner error handling
mechanism we could look at incorporating it.

Well in that other CGI::App-like app I occasionally mention, all errors are handled by one base class which is identical to Class::ErrorHandler. (It should come as no surprise that it written by the same author, Ben Trott.)

If an error is caught or detected (die, bad input, logical error, whatever), the app immediately returns the result of the ErrorHandler->error("message"). In all actuality the error method returns undefined, but the message is stored for later retrieval. The caller, if it receives undefined, can call the ErrorHandler->errstr to retrieve that message. In situations where you have nested method calls you can pass that message back of the stack by doing something like return ErrorHandler2->error(ErrorHandler1->errstr). Anything other then undefined is considered correct operation.

In order to implement something with Class::ErrorHandler for just callbacks, would require a simple subclass class that also holds a reference to the callback method. Here is a some quick scratch code.

package CGI::Application::Plugin::Callback::Object;
use strict;
use base qw( Class::ErrorHandler );
sub new {  bless $_[1], $_[0]; }
sub code { $_[0]->{code} = $_[1]; }
sub run { $_[0]->{code}->(@_); }

The only problem here is handling a string instead of CODE ref.

Ideally though, I would love to see CGI::App implement a scheme like this by using Class:ErrorHandler as its base (which gives all objects from subclasses the error and errstr methods) and make sure all methods return at least a null string unless something has gone wrong.

* Also I think the hook processor should have the option of monitoring
the return value if it so choose. One example is a callback hook that
acts like a filter where any callback returning a false value would
cause some step to be skipped.

How would we actually control that?  Are you suggesting that if a
callback returns a false value, then possibly the next callbacks don't
get executed?

In certain cases, yes. This doesn't apply to any of the base hooks you have implemented. I'm thinking of hooks created by new_hook that act as a filter -- perform a test of some type and either skip or continue with the execution of some function based on that test.

Thoughts?

<tim/>


---------------------------------------------------------------------
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.