Hi Stas,
Stas Bekman wrote:
Can you adjust the original patch to use Symbol and not
Apache::Symbol, so we can re-use the same code in mp1 and mp2? mp2
doesn't carry Apache::Symbol.
No. (Well, not straight-forwardly, anyway.) Apache::Symbol is not a
simple Apache-savvy replacement for Symbol -- it is quite a different
beast.
The patch uses Apache::Symbol::undef_functions(), which wraps calls
to Apache::Symbol::undef(). Neither of these functions are in
Symbol, so I'd have to copy them from Apache::Symbol into
Apache::Reload itself. (And that's more work than it sounds because
undef() is an XSUB.)
Certainly, I just prefer to have the mp1 and mp2 code bases as close
as possible.
Would it not be simpler to put Apache::Symbol back into mp2?
There is no need for it in mp2. We require perl 5.6.1 or higher which
includes filehandle autovivification, via: open my $foo, "bar" or die $!;
If I understand your comment correctly, you're saying that "we don't
need Apache::Symbol in mp2 because there is no need for the gensym()
function that it provides since Perl 5.6.1+ can autovivify filehandles
from the undefined value", yes?
However, the Apache::Symbol module doesn't contain the gensym()
function! It is the Symbol module that provides the gensym() function.
As I said before, Apache::Symbol is something entirely different. It
doesn't contain any functions from the Symbol module; rather, it
contains an undef_functions() function and a very useful XSUB called
undef(), which I still think I need to use. Read on...
Look at ModPerl::RegistryCooker::flush_namespace_normal, which does
the necessary undef'ing. You really need just a chunk of it.
I've had a look at this, and can't get it to work properly. I've
combined the subroutine undef'ing from that function with the constant
subroutine mandatory warning handling from the mp2 version of
Apache::Reload, but when I try it out I find that (a) all the constant
subroutines produce warnings about prototype mismatches, and (b) all the
other subroutines still produce warnings about being redefined!
The following short test script reproduces both of these problems:
### START
use strict;
use warnings;
use constant FOO => 1;
sub bar { 1; }
BEGIN {
$SIG{__WARN__} = sub {
return if $_[0] =~ /^Constant subroutine [\w:]+ redefined at/;
CORE::warn(@_);
};
foreach my $fullname ('main::FOO', 'main::bar') {
if (defined &$fullname) {
if (defined(my $p = prototype $fullname)) {
no strict 'refs';
no warnings 'redefine';
*{$fullname} = eval "sub ($p) {}";
}
else {
no strict 'refs';
no warnings 'redefine';
*{$fullname} = sub {};
}
undef &$fullname;
}
}
}
use constant FOO => 2;
sub bar { 2; }
### END
This program produces the following warnings:
Prototype mismatch: sub main::FOO vs () at C:/perl5/lib/constant.pm line
108.
Subroutine bar redefined at C:\Temp\test.pl line 30.
By contrast, the solution that I was originally working towards, using
Apache::Symbol::undef(), looks much simpler:
### START
use strict;
use warnings;
use constant FOO => 1;
sub bar { 1; }
BEGIN {
require Apache::Symbol;
foreach my $fullname ('main::FOO', 'main::bar') {
no strict 'refs';
Apache::Symbol::undef(*{$fullname}{CODE});
}
}
use constant FOO => 2;
sub bar { 2; }
### END
and produces no warnings.
Unless I'm missing something, this suggests to me that we do still need
(or least, could greatly benefit from having) Apache::Symbol in mp2. I
would like to see it put back so that I can produce an Apache::Reload
patch that uses it.
There are three options here:
1. Put back Apache::Symbol and use it's undef() function.
2. Copy the Apache::Symbol::undef() function into Apache::Reload.
3. Explain why the first test script above doesn't work and fix it!
I favour option 1. What's your vote?
Steve
|