can anyone please explain to me why subroutines resulting
from constants imported with Exporter are not considered
to be defined?
perl -MFcntl -le 'print &F_SETLK'
shows that a subroutine F_SETLK can be called. But
perl -MFcntl -le 'print "defined" if defined &F_SETLK'
shows that it is not considered to be defined.
The consequence is that a constant imported this way can
accidentely be overridden by a 'require "fcntl.ph"'. The
.ph contains (on Linux)
eval 'sub F_SETLK () {6;}' unless defined(&F_SETLK);
but &F_SETLK is not considered to be defined after the use()age
of Fcntl and is thus overridden.
Thanks for any explanations.
Peter
Because you haven't called it : Fcntl constants are autoloaded.
However, it exists.
--
Unilluminating is not *NIX
I believe the problem is that the sub gets autoloaded
the first time it's seen. Your code is testing whether
it's defined before the autoloading has occurred.
From 'perldoc -f defined':
Note that a subroutine which is not defined may still
be callable: its package may have an "AUTOLOAD" method
that makes it spring into existence the first time that
it is called -- see the perlsub manpage.
hth,
--
Charles DeRykus
"Charles DeRykus" <c...@bcstec.ca.boeing.com> wrote in message
news:HqptL...@news.boeing.com...
ok; thanks for the hint.
So I am going to call the sub first to get the constant/sub
spring into existence
$ perl -MFcntl -le 'print &F_SETLK;print "defined" if defined
&F_SETLK'
13
and it still seems not to be defined.
Have I misunderstood the above snippet of perldoc?
Peter
> can anyone please explain to me why subroutines resulting
> from constants imported with Exporter are not considered
> to be defined?
This is INSNHO a bug in Perl.
As a work-round use exists() rather than defined().
> Thanks for any explanations.
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.
Consider:
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.
Now consider:
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.
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\