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.