[cgiapp] can AUTOLOAD sub be named AUTOLOAD?

Darin McBride dmcbride at naboo.to.org
Wed Apr 16 12:38:19 EDT 2008


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.


More information about the cgiapp mailing list