On Wed, 11 Feb 2004, Cees Hek wrote:Interestingly enough, that is actually where I got the motivation to do it this way :) I did search around to see if there were any critisisms of this approach, but I couldn't find anything concrete. Do you have any reasons why it is a bad idea to use this method? I am open to using a different implementation as long as it achieves the same results.
I have two:
1) It's an example of "action at a distance." This is when code in one place (a 'use' line in the CGI::App sub-class) makes unexpected changes in another scope (the CGI::App package). This makes debugging difficult. I've personally had to fix at least 3 bugs related to the weird way that Time::Piece::MySQL works. I don't know if similar bugs would crop up using your module, but they might.
I would reword that to say it makes additions to another scope. It doesn't change anything that already exists in the CGI::Application namespace (ie it is not overwriting any methods). So unless the CGI::Application core actually added methods with the same name, I fail to see how it could affect any existing code? That includes anyone that subclasses CGI::Application and adds their own 'session' method since their version would take precidence in the inheritance tree.
2) Under mod_perl if one CGI::App uses CGI::App::Session then they
all will! And worse, it won't take effect till the first time
the session-using app is loaded, which might make this a real
sleeper bug. I found similar problems with Time::Piece::MySQL
where everything worked great if you happened to already have it
loaded, but in some cases code would fail because some code that
relied on it didn't explicitely load the module.
I can see your point, but you have the same problems with any other module that you forget to load before using it when running under mod_perl or any persistent environment. Although I agree that it might be less obvious where the problem is in this case.
A better way would probably be to have a mechanism to register new plugins with CGI::Application directly. The following is just off the top of my head, but it gives a simple example of what could be done:
That seems reasonable, although I'm not sure the minor problems with inheritence are bad enough to warrent it.
I think it comes down to ease of use, and I think a simple plugin interface would help a lot with that, as well as making it much easier to actually write plugin classes to support other modules (like TT, HTML::FillInForm, etc...).
By having a simple API to write for we can gain a lot with very little work:
- a common way of configuring and loading support modules.
- catch conflicts between modules (ie two modules providing the same helper methods)
- less chance of breaking plugin modules when changes are made to CGI::Application.
- memory/performance savings by only 'require'ing the module if it is needed at runtime.
I'm sure there are more, but that is a start.
Then CGI::Application can dynamically create a stub method in it's own namespace for 'session' and 'session_cookie' that when called will trigger the initialization of the plugin, and then call the real method provided by the plugin.
It shouldn't create anything in its namespace, since that will globally effect all CGI::Apps. Instead, it should implement an AUTOLOAD and use that to lookup per-object plugins.
Fair enough. That would probably be cleaner. I usually try to avoid AUTOLOAD, but in this case it looks like the right tool for the job.
Cheers,
Cees
--------------------------------------------------------------------- Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
