On April 16, 2008 09:48:42 am Perrin Harkins wrote: > > But if the AUTOLOAD problem is a bug that can be fixed > > easily, then I'd rather do that than use this workaround. > > I have no idea if it's a bug or not, but a sub called AUTOLOAD has a > well-known meaning in Perl which you are not entirely following here, > and that seems very confusing to me. It's kind of like wanting to > call your custom cleanup method DESTROY.
This looks like a minor bug to me - CA is reusing a well-known meme in a way that doesn't quite work. When I started using CA, the ability to just specify runmodes and subs that were the same name didn't exist, so having C<AUTOLOAD => \&catchall> was not any worse than also having to specify C<myrunmode => \&myrunmode>. Now, there is an indirect implicit suggestion to use a sub called 'AUTOLOAD' to handle the 'AUTOLOAD' action, based on the perldoc: Often, it makes good organizational sense to have your run modes map to methods of the same name. The array-ref interface provides a shortcut to that behavior while reducing verbosity of your code. My suggestion is that AUTOLOAD is not, and never has been, a runmode. No one should be able to load http://myapp.net/?rm=AUTOLOAD. I've not tested to see if that actually calls the AUTOLOAD runmode or not, but it shouldn't. (I suspect it does.) Instead, if I want the fallback, I should not be setting a run_mode, I should be setting a fallback: $self->fallback_mode('my_catchall_sub'); This is something that should be callable only in cases where the fallback is required. Something like this: ------------------- --- Application.pm.orig 2008-04-16 10:15:17.000000000 -0600 +++ Application.pm 2008-04-16 10:32:13.000000000 -0600 @@ -135,14 +135,14 @@ my $rmeth; my $autoload_mode = 0; - if (exists($rmodes{$rm})) { + if (exists($rmodes{$rm}) and $rm ne 'AUTOLOAD') { $rmeth = $rmodes{$rm}; } else { - # Look for run mode "AUTOLOAD" before dieing - unless (exists($rmodes{'AUTOLOAD'})) { + # Look for fallback mode before dieing + $rmeth = $self->fallback_mode(); + unless ($rmeth) { croak("No such run mode '$rm'"); } - $rmeth = $rmodes{'AUTOLOAD'}; $autoload_mode = 1; } @@ -526,6 +526,24 @@ } +sub fallback_mode { + my $self = shift; + my ($fallback_mode) = @_; + + # First use? Create new __FALLBACK_MODE + $self->{__FALLBACK_MODE} = undef unless (exists($self->{__FALLBACK_MODE})); + + # If data is provided, set it. + if (defined($fallback_mode)) { + $self->{__FALLBACK_MODE} = $fallback_mode; + } + + # if we have a fallback, use it, if we have the old deprecated + # AUTOLOAD mode, use that instead. + return $self->{__FALLBACK_MODE} || {$self->run_modes()}{AUTOLOAD}; +} + + sub tmpl_path { my $self = shift; my ($tmpl_path) = @_; ------------------- Of course, CAP::AutoRunmode would need a flag for that, too - I'm not providing a sample patch for that ;-) > Or maybe I just have a chip on my shoulder because I think obsession > with syntax is one of the more self-destructive traits of the Perl > community. Sometimes that obsession finds holes. And, depending on how poorly your autoload is written, that hole may be security-related. But, in reality, syntax is about communication between author and computer. And clear, concise syntax is about maintainability. I wish my coworkers were as concerned with syntax as many in the Perl community. ##### CGI::Application community mailing list ################ ## ## ## To unsubscribe, or change your message delivery options, ## ## visit: http://www.erlbaum.net/mailman/listinfo/cgiapp ## ## ## ## Web archive: http://www.erlbaum.net/pipermail/cgiapp/ ## ## Wiki: http://cgiapp.erlbaum.net/ ## ## ## ################################################################