defined(&func) and Exporter

Answer

This is a bug in Perl. As a work-round use exists() rather than defined().

It has something to do with a bit of DWIMery what happens if you take a reference to function that has not yet been defined. This DWIMery exists so that you can export autoloaded functions.

sub one { 'one' };
sub foo { 'zero' };
my $bar = \&foo;
print \&foo,$bar; # Prints the same thing twice
*foo = \&one; # Emits redefined warning
print $bar->(); # Prints zero
print \&foo,$bar; # Prints different things
eval "sub foo { 'two' }"; # Emits redefined warning
print $bar->(); # Still prints zero
print 0+defined(&$bar); # Prints 1

All that seems in line with how one expects hard code references to behave.

sub one { 'one' };
my $bar = \&foo; # &foo does not yet exist
print \&foo,$bar; # Prints the same thing twice
*foo = \&one;
print \&foo,$bar; # Prints different things
print $bar->(); # Prints one
eval "sub foo { 'two' }"; # Emits redefined warning
print $bar->(); # Prints two

The supposedly hard code reference $bar is actually behaving as if it were a symbolic reference to &main::foo.

However in this case...

print 0+defined(&$bar); # Prints 0

...and this as I said before, IMNSHO, is a bug in Perl. It should print 1.

Next