Hello,

I have seen some posts regarding Constant.pm problems with exporting
"constants",
but in my opinion some problems are still not solved.

More general potential problem:

In Constant.pm there is a code reading <DATA> filehandle.
We can find

seek(DATA,0,0);

I tried this with some different versions of perl, especially Debian
ones,
and found this is bad, because offset of 0 points to the beginning
of file, not just after __DATA__ or __END__ tag.

So after seek like this routine is parsing also perl code,
not "pod" documentation only.
Im sure of that, because I made some debug in Constant.pm
dumping data read from <DATA> and also tried in my own scripts.
Also when you start some program and
do tell(DATA), result actually is not 0.

Probably there should be some global variable like:

my $DATA_begin_offset;

used before seek; if not defined (used for the first time)
it gets inital DATA offset, which is actual DATA begin:
defined($DATA_begin_offset) or $DATA_begin_offset = tell(DATA);
seek(DATA, $DATA_begin_offset,0);

Other problem is more Perl specific, but can explain why
do people get "not exported" errors:

Some compilation of perl, especially Debian compilations,
shows strange <DATA> behaviour.
Even if you start reading DATA in bunch of forked processes
AFTER fork operation, process which first started to read
"slurps" some buffer from <DATA> so other processes
see DATA not from beginning, but from some offset.
That's why sometimes Constant::import() cannot find
some definitions in "pod" part.
seek() does not help here !

Problem can be hard to track, I experienced it
when using Net::LDAP in my own ModPerl based
Apache authorization module. Sometimes after
restarting Apache when multiple users are connecting
and being authorized, one of processess ends up
with mess as described above.

When I analyzed Constant.pm, I wrote script
for repeating the problem
(it's important to add 1000 or more lines
to the __DATA__ section)

#!/usr/bin/perl -w

# Problem 1:
#
# DATA is shared amongst spawned processes.
# "Faster" process allocates some DATA buffer,
# other process reads from point after buffer
# allocated by first process:

# Problem 2:
#
# If you do seek(DATA,0,0),
# data starts on the very beginning of this file,
# NOT after __DATA__ tag.

# That's why using DATA can be VERY BAD.

my $pid = fork;
unless(defined($pid)) { die("fork failed: '$!'") }
print("My PID: $$\n");
seek(DATA,0,0);
select(undef(),undef(),undef(),rand(1));
my $who = $pid ? 'p' : 'c';
while(<DATA>)
{
  print("$who $$: $_");
  select(undef(),undef(),undef(),rand(1));
}
if($pid) { wait(); }
__DATA__
d1
d2
d3
# PUT 1000 more lines with subsequent numbers here to see the bad
behaviour!

With some perl compilations you can see that process
which started to read first displays first lines, no matter
if process is parent (p) or child(c). Other process starts
reading from some further line.

At the moment I'm doing
use Net::LDAP::Constant qw(:all);
before forking to avoid the problems later.

Of course perl compilations should be fixed,
but doing some workaround in Constant.pm  would be nice
for many users. Especially explicit definitions in earlier
versions of Constant.pm are working very well.

Regards

Reply via email to