Overriding Methods with Non-Existent Methods

Today I spent a few hours trying to nail down a nasty bug. Once I could replicate a small test case, what finally clued me in was an error message that looked impossible, but I remembered seeing it somewhere before. I just couldn't remember where. Consider this:

if ($c->user || $c->authenticate(undef, 'Pips Realm')) {

That was failing with "Undefined subroutine &Pips3::user called at..."

Wait! What? I didn't call a subroutine. I called a method! What the hell is going on?

For our tests, we sometimes override the authenticated user in our Pips3 application. The core of this code looks like this:

When you call 'new' with a valid user name, you get a token back and while it is in scope, you have overridden the user for the application. I was quite happy with this code, but there's a nasty, nasty bug in it. Once I remembered what it was, the fix was painfully obvious.

In Perl, when you try to pull a coderef out of a typeglob, you sometimes get some strange behavior:

As you can see, you apparently get a code reference. If you try to call it, though, it will give the following error message "Undefined subroutine &main::no_such_subroutine called at...". It even remembers the name of the non-existent subroutine! Even stranger:

#!/usr/bin/perl -l

sub Foo::bar {'foo'}*Foo::baz = \&::baz;

print Foo->bar;print Foo->baz;__END__fooUndefined subroutine &main::baz called at test.pl line 7.

Wait! What? I didn't call a subroutine. I called a method! What the hell is going on?

Ooooooohhhhhhhh.

In Catalyst, when you use a plugin, your application gets the methods because it inherits them. It doesn't install them into your namespace. Thus, when Pips3 used the authentication plugin, my constructor above, trying to grab a reference to &Pips3::user, was clearly stupid. What's worse, when I tried to restore it, I had a non-existent method overriding an existing one! How's that for a blunder? The fix is simple:

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
Without JavaScript enabled, you might want to
use the classic discussion system instead. If you login, you can remember this preference.