I recently sent a patch for Apache::Reload to that module's original > author - Matt Sergeant - but he replied to say that he's now given > control of that module to you. I'm therefore forwarding the patch to you.
No, that's incorrect. I'm not the owner of this module. All I have asked Matt is to let me perms to upload Apache/Reload.pm as part of mod_perl 2.0. I haven't taken over the maintenance of this module.
Currently there are two versions of this module. One on CPAN for mod_perl 1.0, the other inside the mod_perl 2.0 package. The mod_perl developers collectively maintain the version in 2.0, but not the CPAN version. Perhaps what should be done is backport the module in 2.0 to mod_perl 1.0.
Also Philippe may consider to put Apache/Reload.pm into the 1.0 distro as well.
Now Steve, to your original question. You want these changes for mod_perl 1.0, correct?
If you try the version in the 2.0 package it already includes all the changes that you ask for. However it won't work with 1.0 as is, since it deploys the 2.0 API.
Could you possibly have a look at it?>
I'm after two things: an "UndefOnReload" option like Apache::StatINC has > (which I haven't quite got working to my satisfaction yet), and a > GPL/Artistic license statement (like I recently requested for your > Apache::Test module, in fact!)>
Many thanks,>
Steve>
-------- Original Message --------> Subject: Apache::Reload Module> Date: Mon, 19 May 2003 10:12:21 +0100> From: Steve Hay <steve.hay@uk.radan.com>> To: matt@sergeant.org>
Hi Matt,>
I'm looking into using your Apache::Reload module as an improvement over > the Apache::StatINC module, but found that one feature was missing from > it: the option to have functions undefined on reload to avoid all those > "Subroutine ... redefined ..." warnings.>
The attached patch provides this option (but not quite to my > satisfaction). Specify "PerlSetVar UndefOnReload On" in httpd.conf and > the handler performs the same undeffing action (using > Apache::Symbol::undef_functions) as Apache::StatINC does...>
... well, almost! Apache::StatINC calls undef_functions(undef, 1) which > arranges for ONLY functions specified in the EXPORT arrays (including a > special @EXPORT_EXTRAS array) to be undefined.>
This is not very nice for OO-code which doesn't list its methods in the > EXPORT arrays, so initially I looked at calling undef_functions(undef, > 0), which would undefine all functions in the class concerned. However, > I found that this includes sub-classes too, so, for example, if I have > Foo:: functions and Foo::Bar:: functions and I edit Foo.pm then all the > Foo::Bar:: functions get undefined too, but not reloaded since I haven't > edited Foo/Bar.pm!>
My latest attempt (in the patch) is undef_functions("^${class}::.+::", > 0), which will undefine all functions in $class, but skips those > matching the pattern in the first argument. This avoids the Foo::Bar:: > problem described above.>
However, there is still one gremlin left that I don't know how to get > around. If Foo use()s the Exporter module then Foo::import is an alias > for Exporter::import, so when Foo::import is undefined we find that > Exporter::import is now also undefined (and, of course, doesn't get > reloaded since Exporter.pm has not been edited)! This applies to any > symbols that Foo has imported.>
Can you think of a way around that last problem? Maybe Apache::Symbol > needs some work?>
If not, then probably going back to undef_functions(undef, 1) is safer.>
One last point: I want to put this module into a Perl distribution that > is being shipped with some (commercial, not open source) software, and I > would need it to have a LICENSE statement somewhere in it, which it > currently doesn't have. Preferably the usual blurb about "the same > terms as Perl itself -- GPL or Artistic" since just the GPL (which, > sadly, some modules do specify) would not permit inclusion in such a > commercial distribution.>
A new release with either or both of these things in it would be greatly > appreciated.>
[please be sure to keep me in the loop here -- I'm not subscribed to the dev list]
Currently there are two versions of this module. One on CPAN for > mod_perl 1.0, the other inside the mod_perl 2.0 package. The mod_perl > developers collectively maintain the version in 2.0, but not the CPAN > version. Perhaps what should be done is backport the module in 2.0 to > mod_perl 1.0.>
Also Philippe may consider to put Apache/Reload.pm into the 1.0 distro > as well.
Backporting the version in mp2 to mp1 and including it in mp1 sounds like an excellent idea for the forthcoming 1.28 release.
Would Matt & Philippe agree to this?
Now Steve, to your original question. You want these changes for > mod_perl 1.0, correct?
Yes.
If you try the version in the 2.0 package it already includes all the > changes that you ask for. However it won't work with 1.0 as is, since > it deploys the 2.0 API.
Unless I'm missing something, this doesn't seem to be the case. I've just downloaded the latest mp2 and checked it out. It doesn't have a "UndefOnReload" option or any equivalent thereof (and it doesn't automatically do what that option would do all the time either).
Steve
Could you possibly have a look at it?>>
I'm after two things: an "UndefOnReload" option like Apache::StatINC >> has (which I haven't quite got working to my satisfaction yet), and a >> GPL/Artistic license statement (like I recently requested for your >> Apache::Test module, in fact!)>>
Many thanks,>>
Steve>>
-------- Original Message -------->> Subject: Apache::Reload Module>> Date: Mon, 19 May 2003 10:12:21 +0100>> From: Steve Hay <steve.hay@uk.radan.com>>> To: matt@sergeant.org>>
Hi Matt,>>
I'm looking into using your Apache::Reload module as an improvement >> over the Apache::StatINC module, but found that one feature was >> missing from it: the option to have functions undefined on reload to >> avoid all those "Subroutine ... redefined ..." warnings.>>
The attached patch provides this option (but not quite to my >> satisfaction). Specify "PerlSetVar UndefOnReload On" in httpd.conf >> and the handler performs the same undeffing action (using >> Apache::Symbol::undef_functions) as Apache::StatINC does...>>
... well, almost! Apache::StatINC calls undef_functions(undef, 1) >> which arranges for ONLY functions specified in the EXPORT arrays >> (including a special @EXPORT_EXTRAS array) to be undefined.>>
This is not very nice for OO-code which doesn't list its methods in >> the EXPORT arrays, so initially I looked at calling >> undef_functions(undef, 0), which would undefine all functions in the >> class concerned. However, I found that this includes sub-classes >> too, so, for example, if I have Foo:: functions and Foo::Bar:: >> functions and I edit Foo.pm then all the Foo::Bar:: functions get >> undefined too, but not reloaded since I haven't edited Foo/Bar.pm!>>
My latest attempt (in the patch) is >> undef_functions("^${class}::.+::", 0), which will undefine all >> functions in $class, but skips those matching the pattern in the >> first argument. This avoids the Foo::Bar:: problem described above.>>
However, there is still one gremlin left that I don't know how to get >> around. If Foo use()s the Exporter module then Foo::import is an >> alias for Exporter::import, so when Foo::import is undefined we find >> that Exporter::import is now also undefined (and, of course, doesn't >> get reloaded since Exporter.pm has not been edited)! This applies to >> any symbols that Foo has imported.>>
Can you think of a way around that last problem? Maybe >> Apache::Symbol needs some work?>>
If not, then probably going back to undef_functions(undef, 1) is safer.>>
One last point: I want to put this module into a Perl distribution >> that is being shipped with some (commercial, not open source) >> software, and I would need it to have a LICENSE statement somewhere >> in it, which it currently doesn't have. Preferably the usual blurb >> about "the same terms as Perl itself -- GPL or Artistic" since just >> the GPL (which, sadly, some modules do specify) would not permit >> inclusion in such a commercial distribution.>>
A new release with either or both of these things in it would be >> greatly appreciated.>>
Steve Hay wrote: [...]>> If you try the version in the 2.0 package it already includes all the >> changes that you ask for. However it won't work with 1.0 as is, since >> it deploys the 2.0 API. >
Unless I'm missing something, this doesn't seem to be the case. I've > just downloaded the latest mp2 and checked it out. It doesn't have a > "UndefOnReload" option or any equivalent thereof (and it doesn't > automatically do what that option would do all the time either).
IMHO, you don't need this option. Apache::Reload does it automatically:
no warnings 'redefine'; require $file;
If your module, afterwards does:
use warnings;
it's a problem of your module. Simple replace it with:
use warnings; no warnings 'redefine';
Does this work for you? Or do you think that it's better to do an explicit symbols undef?
If you try the version in the 2.0 package it already includes all >>> the changes that you ask for. However it won't work with 1.0 as is, >>> since it deploys the 2.0 API. >>
Unless I'm missing something, this doesn't seem to be the case. I've >> just downloaded the latest mp2 and checked it out. It doesn't have a >> "UndefOnReload" option or any equivalent thereof (and it doesn't >> automatically do what that option would do all the time either).>
IMHO, you don't need this option. Apache::Reload does it automatically:>
no warnings 'redefine';> require $file;
It actually overkills it with "no warnings FATAL => 'all';", but this is irrelevant anyway -- "use warnings" / "no warnings" are lexically scoped. The line "require $file" doesn't generate any warnings within that lexical scope, so turning warnings off there doesn't achieve anything. The "redefine" warnings come from the lexical scope of the file that it being reloaded.
If your module, afterwards does:>
use warnings;>
it's a problem of your module.
This is what all of my modules do, at least while under development -- which is also the scenario in which I want to make use of Apache::Reload! I don't see this as a "problem" of my module -- it's what I always do, and is recommended by various venerable sources.
Simple replace it with:>
use warnings;> no warnings 'redefine';>
Does this work for you? Or do you think that it's better to do an > explicit symbols undef?
Yes, of course, this works for me, but I don't want to turn any warnings off. Supposing my module accidentally does redefine a subroutine? Maybe I'm mucking about with two different versions of a subroutine, and have accidentally left them both active. I'd like to know about that! It also wouldn't work for anyone running under "perl -W", which overrides all other means of disabling warnings.
I would therefore prefer to have an explicit symbols undef done. I don't necessarily want an *option* for it, though -- I'd be happy if it *always* did that. Would you ever want to see those redefine warnings? If so, then maybe have an "UndefOnReload" option that defaults to "On", and users can turn it "Off" if they wish -- like your "ReloadConstantRedefineWarnings" option. (Presumably you would consolidate both of these things into one single option.)
On Friday, Jun 13, 2003, at 09:02 Europe/London, Steve Hay wrote:
Currently there are two versions of this module. One on CPAN for >> mod_perl 1.0, the other inside the mod_perl 2.0 package. The mod_perl >> developers collectively maintain the version in 2.0, but not the CPAN >> version. Perhaps what should be done is backport the module in 2.0 >> to mod_perl 1.0.>>
Also Philippe may consider to put Apache/Reload.pm into the 1.0 >> distro as well.>
Backporting the version in mp2 to mp1 and including it in mp1 sounds > like an excellent idea for the forthcoming 1.28 release.>
Would Matt & Philippe agree to this?
I'd be much happier for someone to take over maintainence as my workload is way to high to deal with this right now. I always planned for Apache::Reload to be included in mod_perl anyway (as a StatINC replacement).
If you try the version in the 2.0 package it already includes all >>>> the changes that you ask for. However it won't work with 1.0 as is, >>>> since it deploys the 2.0 API. >>>
Unless I'm missing something, this doesn't seem to be the case. I've >>> just downloaded the latest mp2 and checked it out. It doesn't have a >>> "UndefOnReload" option or any equivalent thereof (and it doesn't >>> automatically do what that option would do all the time either).>>
IMHO, you don't need this option. Apache::Reload does it automatically:>>
no warnings 'redefine';>> require $file; >
It actually overkills it with "no warnings FATAL => 'all';", but this is > irrelevant anyway -- "use warnings" / "no warnings" are lexically > scoped. The line "require $file" doesn't generate any warnings within > that lexical scope, so turning warnings off there doesn't achieve > anything. The "redefine" warnings come from the lexical scope of the > file that it being reloaded.
True.
If your module, afterwards does:>>
use warnings;>>
it's a problem of your module.>
This is what all of my modules do, at least while under development -- > which is also the scenario in which I want to make use of > Apache::Reload! I don't see this as a "problem" of my module -- it's > what I always do, and is recommended by various venerable sources.
I do the same.
Simple replace it with:>>
use warnings;>> no warnings 'redefine';>>
Does this work for you? Or do you think that it's better to do an >> explicit symbols undef? >
Yes, of course, this works for me, but I don't want to turn any warnings > off. Supposing my module accidentally does redefine a subroutine? Maybe > I'm mucking about with two different versions of a subroutine, and have > accidentally left them both active. I'd like to know about that! It > also wouldn't work for anyone running under "perl -W", which overrides > all other means of disabling warnings.>
I would therefore prefer to have an explicit symbols undef done. I > don't necessarily want an *option* for it, though -- I'd be happy if it > *always* did that. Would you ever want to see those redefine warnings? > If so, then maybe have an "UndefOnReload" option that defaults to "On", > and users can turn it "Off" if they wish -- like your > "ReloadConstantRedefineWarnings" option. (Presumably you would > consolidate both of these things into one single option.)
You are correct.
Since we are talking about undef-ing only CODE refs, the option should have a good mnemonic, "UndefOnReload" doesn't imply subs. So I suggest to have
ReloadSubRedefineWarnings off
with default being 'on' - no action taken. Or ReloadSubroutineRedefineWarnings.
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.
Matt wrote:> On Friday, Jun 13, 2003, at 09:02 Europe/London, Steve Hay wrote:>
Currently there are two versions of this module. One on CPAN for >>> mod_perl 1.0, the other inside the mod_perl 2.0 package. The mod_perl >>> developers collectively maintain the version in 2.0, but not the CPAN >>> version. Perhaps what should be done is backport the module in 2.0 >>> to mod_perl 1.0.>>>
Also Philippe may consider to put Apache/Reload.pm into the 1.0 >>> distro as well.>>
Backporting the version in mp2 to mp1 and including it in mp1 sounds >> like an excellent idea for the forthcoming 1.28 release.>>
Would Matt & Philippe agree to this?>
I'd be much happier for someone to take over maintainence as my workload > is way to high to deal with this right now. I always planned for > Apache::Reload to be included in mod_perl anyway (as a StatINC > replacement).
What we can do is to put it into 1.28's release and phase out its standalone package-existence. Those wanting the lastest Apache::Reload against the older packages will get it from 1.28.
Hopefully Philippe won't mind to include it in the 1.28 release.
[Matt - Shall we drop you from this discussion now, or are you still interested?]
Hi Stas,
Stas Bekman wrote:
Steve Hay wrote:>
I would therefore prefer to have an explicit symbols undef done. I >> don't necessarily want an *option* for it, though -- I'd be happy if >> it *always* did that. Would you ever want to see those redefine >> warnings? If so, then maybe have an "UndefOnReload" option that >> defaults to "On", and users can turn it "Off" if they wish -- like >> your "ReloadConstantRedefineWarnings" option. (Presumably you would >> consolidate both of these things into one single option.)>
You are correct.>
Since we are talking about undef-ing only CODE refs, the option should > have a good mnemonic, "UndefOnReload" doesn't imply subs. So I suggest > to have>
ReloadSubRedefineWarnings off>
with default being 'on' - no action taken. Or > ReloadSubroutineRedefineWarnings.
I'd agree with that.
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.)
Would it not be simpler to put Apache::Symbol back into mp2?
Steve Hay wrote:> [Matt - Shall we drop you from this discussion now, or are you still > interested?]
Matt is on the dev list, so I've removed him from CC.
I would therefore prefer to have an explicit symbols undef done. I >>> don't necessarily want an *option* for it, though -- I'd be happy if >>> it *always* did that. Would you ever want to see those redefine >>> warnings? If so, then maybe have an "UndefOnReload" option that >>> defaults to "On", and users can turn it "Off" if they wish -- like >>> your "ReloadConstantRedefineWarnings" option. (Presumably you would >>> consolidate both of these things into one single option.)
You are correct.>>
Since we are talking about undef-ing only CODE refs, the option should >> have a good mnemonic, "UndefOnReload" doesn't imply subs. So I suggest >> to have>>
ReloadSubRedefineWarnings off>>
with default being 'on' - no action taken. Or >> ReloadSubroutineRedefineWarnings. >
I'd agree with that.
Good.
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 $!;
Look at ModPerl::RegistryCooker::flush_namespace_normal, which does the necessary undef'ing. You really need just a chunk of it.
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!
Philippe M. Chiasson 18 June 2003 07:44:56 [ permanent link ]
On Mon, 2003-06-16 at 17:45, Stas Bekman wrote:> Matt wrote:> > On Friday, Jun 13, 2003, at 09:02 Europe/London, Steve Hay wrote:> >
Currently there are two versions of this module. One on CPAN for > >>> mod_perl 1.0, the other inside the mod_perl 2.0 package. The mod_perl > >>> developers collectively maintain the version in 2.0, but not the CPAN > >>> version. Perhaps what should be done is backport the module in 2.0 > >>> to mod_perl 1.0.> >>>
Also Philippe may consider to put Apache/Reload.pm into the 1.0 > >>> distro as well.
Absolutely a good idea!
Backporting the version in mp2 to mp1 and including it in mp1 sounds > >> like an excellent idea for the forthcoming 1.28 release.> >>
Would Matt & Philippe agree to this?> >
I'd be much happier for someone to take over maintainence as my workload > > is way to high to deal with this right now. I always planned for > > Apache::Reload to be included in mod_perl anyway (as a StatINC > > replacement).>
What we can do is to put it into 1.28's release and phase out its standalone > package-existence. Those wanting the lastest Apache::Reload against the older > packages will get it from 1.28.
Sounds like a good idea.
Hopefully Philippe won't mind to include it in the 1.28 release.
I sure do not mind. How much work is needed in order to backport it to mp1? Anybody actually doing it, or is gonna have to be me ? In which case I could probably get around doing it this week sometime.
---------------------------------------------------------------------> To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org> For additional commands, e-mail: dev-help@perl.apache.org
-- -------------------------------------------------------------------------------- Philippe M. Chiasson /gozer\@(cpan|ectoplasm)\.org/ 88C3A5A5 (122FF51B/C634E37B) http://gozer.ectoplasm.org/ F9BF E0C2 480E 7680 1AE5 3631 CB32 A107 88C3 A5A5 Q: It is impossible to make anything foolproof because fools are so ingenious. perl -e'$$=\${gozer};{$_=unpack(P7,pack(L,$$));/^JAm_pH\n$/&&print||$$++&&redo}'
Philippe M. Chiasson 18 June 2003 08:09:43 [ permanent link ]
On Fri, 2003-06-13 at 16:02, Steve Hay wrote:> Hi Stas,>
Stas Bekman wrote:>
[CC'ing Matt and the dev list] >
[please be sure to keep me in the loop here -- I'm not subscribed to the > dev list]>
Currently there are two versions of this module. One on CPAN for > > mod_perl 1.0, the other inside the mod_perl 2.0 package. The mod_perl > > developers collectively maintain the version in 2.0, but not the CPAN > > version. Perhaps what should be done is backport the module in 2.0 to > > mod_perl 1.0.> >
Also Philippe may consider to put Apache/Reload.pm into the 1.0 distro > > as well. >
Backporting the version in mp2 to mp1 and including it in mp1 sounds > like an excellent idea for the forthcoming 1.28 release.>
Would Matt & Philippe agree to this?>
Now Steve, to your original question. You want these changes for > > mod_perl 1.0, correct? >
Yes.>
If you try the version in the 2.0 package it already includes all the > > changes that you ask for. However it won't work with 1.0 as is, since > > it deploys the 2.0 API. >
Unless I'm missing something, this doesn't seem to be the case. I've > just downloaded the latest mp2 and checked it out. It doesn't have a > "UndefOnReload" option or any equivalent thereof (and it doesn't > automatically do what that option would do all the time either).>
Steve>
Could you possibly have a look at it?> >>
I'm after two things: an "UndefOnReload" option like Apache::StatINC > >> has (which I haven't quite got working to my satisfaction yet), and a > >> GPL/Artistic license statement (like I recently requested for your > >> Apache::Test module, in fact!)> >>
Many thanks,> >>
Steve> >>
-------- Original Message --------> >> Subject: Apache::Reload Module> >> Date: Mon, 19 May 2003 10:12:21 +0100> >> From: Steve Hay <steve.hay@uk.radan.com>> >> To: matt@sergeant.org> >>
Hi Matt,> >>
I'm looking into using your Apache::Reload module as an improvement > >> over the Apache::StatINC module, but found that one feature was > >> missing from it: the option to have functions undefined on reload to > >> avoid all those "Subroutine ... redefined ..." warnings.> >>
The attached patch provides this option (but not quite to my > >> satisfaction). Specify "PerlSetVar UndefOnReload On" in httpd.conf > >> and the handler performs the same undeffing action (using > >> Apache::Symbol::undef_functions) as Apache::StatINC does...> >>
... well, almost! Apache::StatINC calls undef_functions(undef, 1) > >> which arranges for ONLY functions specified in the EXPORT arrays > >> (including a special @EXPORT_EXTRAS array) to be undefined.> >>
This is not very nice for OO-code which doesn't list its methods in > >> the EXPORT arrays, so initially I looked at calling > >> undef_functions(undef, 0), which would undefine all functions in the > >> class concerned. However, I found that this includes sub-classes > >> too, so, for example, if I have Foo:: functions and Foo::Bar:: > >> functions and I edit Foo.pm then all the Foo::Bar:: functions get > >> undefined too, but not reloaded since I haven't edited Foo/Bar.pm!> >>
My latest attempt (in the patch) is > >> undef_functions("^${class}::.+::", 0), which will undefine all > >> functions in $class, but skips those matching the pattern in the > >> first argument. This avoids the Foo::Bar:: problem described above.> >>
However, there is still one gremlin left that I don't know how to get > >> around. If Foo use()s the Exporter module then Foo::import is an > >> alias for Exporter::import, so when Foo::import is undefined we find > >> that Exporter::import is now also undefined (and, of course, doesn't > >> get reloaded since Exporter.pm has not been edited)! This applies to > >> any symbols that Foo has imported.> >>
Can you think of a way around that last problem? Maybe > >> Apache::Symbol needs some work?> >>
If not, then probably going back to undef_functions(undef, 1) is safer.> >>
One last point: I want to put this module into a Perl distribution > >> that is being shipped with some (commercial, not open source) > >> software, and I would need it to have a LICENSE statement somewhere > >> in it, which it currently doesn't have. Preferably the usual blurb > >> about "the same terms as Perl itself -- GPL or Artistic" since just > >> the GPL (which, sadly, some modules do specify) would not permit > >> inclusion in such a commercial distribution.> >>
A new release with either or both of these things in it would be > >> greatly appreciated.
Here is some code I've ripped from an in-house Apache::Reload equivalent... It's a bit convoluted, but does work quite nicely.
sub _removeModule { my $recursive = shift; my $create = $recursive ? 'rnew' : 'new';
no strict 'refs'; my @removed;
if ($package eq __PACKAGE__ || $package =~ /^(B|Devel)::/ || $package !~ /::/) {#suicide ? I don't think so...
#we do not attempt to reload either ourselves, B and Devel packages and Top level packages return; }
if ($package->can('bootstrap')) #should be a more safe way to figure it out than this {#XS/C code, very bad for now ! BAIL out print STDERR "$package contains non-perl code and can't be reloaded for now\n"; return; }
my $stab = Devel::Symdump->$create($package);
my @methods = grep {$_ !~ /^(packages|ios|functions)$/} sort keys %{$stab->{'AUTOLOAD'}};
for my $type ('packages', 'ios', @methods, 'functions') { (my $dtype = uc $type) =~ s/E?S$//;
for (sort $stab->_partdump(uc $type)) { s/([\000-\037\177])/ '^' . pack('c',ord($1) ^ 64)/eg; next if /::SUPER(::.*)?$/;
if ($type eq 'scalars') { next unless defined $$_; } elsif ($type eq 'packages') { next unless $recursive; push @removed, _removeModule($_, 'recursive'); } elsif ($type eq 'functions') { my $stash = B::svref_2object(*$_{CODE})->GV->STASH->NAME; next if $stash ne $package; } &{"undef_$dtype"} ($_) if defined &{"undef_$dtype"}; } }
---------------------------------------------------------------------> To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org> For additional commands, e-mail: dev-help@perl.apache.org
-- -------------------------------------------------------------------------------- Philippe M. Chiasson /gozer\@(cpan|ectoplasm)\.org/ 88C3A5A5 (122FF51B/C634E37B) http://gozer.ectoplasm.org/ F9BF E0C2 480E 7680 1AE5 3631 CB32 A107 88C3 A5A5 Q: It is impossible to make anything foolproof because fools are so ingenious. perl -e'$$=\${gozer};{$_=unpack(P7,pack(L,$$));/^JAm_pH\n$/&&print||$$++&&redo}'
Here is some code I've ripped from an in-house Apache::Reload>equivalent... It's a bit convoluted, but does work quite nicely.>
Thanks for the code -- it looks excellent to me.
I've attached a patch for Apache::Reload that makes use of your code to achieve what I'm after. The patch is against the Apache::Reload currently in mp2 cvs. Things to note:
1. I've removed Apache::ServerUtil and Apache::RequestUtil -- they didn't seem to be being used. 2. I've removed the ConstantRedefineWarnings option because your code makes use of Apache::Symbol::undef() which avoids those warnings anyway. 3. I've removed the part of your code that skipped removing top-level packages -- I (perhaps unwisely) use such names a lot!
If this is going to be put into mp2 (which I certainly hope it is) then Apache::Symbol will need to be put back too since your code relies on it.
I've also attached a patch that will produce a mp1-compatible version of the same: Start with the current cvs mp2 Apache::Reload and apply the main patch to it, then apply the "for_mp1" patch to that.
I've quickly tested this mp1-compatible version, and it seems to be working so far: no "subroutine redefined" warnings are being produced (not even for constant subroutines), and imported subroutines are not being mistakenly undefined. I hope this can be added to mp1.28 (which already has Apache::Symbol, of course).
use Apache::Connection; use Apache::Symbol; @@ -155,7 +153,7 @@ $Stat{$file} = $mtime; }
- return Apache::OK; + return OK; }
sub remove_package {
--------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org For additional commands, e-mail: dev-help@perl.apache.org
Philippe M. Chiasson 18 June 2003 18:49:29 [ permanent link ]
On Wed, 2003-06-18 at 17:19, Steve Hay wrote:> Hi Philippe,>
Philippe M. Chiasson wrote:>
Here is some code I've ripped from an in-house Apache::Reload> >equivalent... It's a bit convoluted, but does work quite nicely.> >
Thanks for the code -- it looks excellent to me.
no problem
I've attached a patch for Apache::Reload that makes use of your code to > achieve what I'm after. The patch is against the Apache::Reload > currently in mp2 cvs. Things to note:>
1. I've removed Apache::ServerUtil and Apache::RequestUtil -- they > didn't seem to be being used.> 2. I've removed the ConstantRedefineWarnings option because your code > makes use of Apache::Symbol::undef() which avoids those warnings anyway.> 3. I've removed the part of your code that skipped removing top-level > packages -- I (perhaps unwisely) use such names a lot!>
If this is going to be put into mp2 (which I certainly hope it is) then > Apache::Symbol will need to be put back too since your code relies on it.>
I've also attached a patch that will produce a mp1-compatible version of > the same: Start with the current cvs mp2 Apache::Reload and apply the > main patch to it, then apply the "for_mp1" patch to that.
And integrate that into an mod_perl 1 & 2 Apache::Reload instead? I would rather not have to maintain 2 ever so slightly different versions of Apache::Reload if that can be avoided.
I've quickly tested this mp1-compatible version, and it seems to be > working so far: no "subroutine redefined" warnings are being produced > (not even for constant subroutines), and imported subroutines are not > being mistakenly undefined. I hope this can be added to mp1.28 (which > already has Apache::Symbol, of course).
Just might
I guess Apache::Symbol might need to be re-created for mp2. According to : $> fgrep Apache::Symbpl mp2/docs/deprecated_features.txt + Apache::Symbol: unknown
There are only 3 functions in there, and they are: undef sv_name cv_const_sv
I don't see why we can't find some room for those somewhere in mp2, especially the magical 'undef' function in there.
Stas: BTW, for Apache::Reload, to get rid of that constant subroutine redefined, that XS implemtation would get rid of it without a need for skip_redefine_const_sub_warn. No more $SIG{__WARN__}
How about if I ported Apache::Symbol::undef to ModPerl::Util::undef ?
-- -------------------------------------------------------------------------------- Philippe M. Chiasson /gozer\@(cpan|ectoplasm)\.org/ 88C3A5A5 (122FF51B/C634E37B) http://gozer.ectoplasm.org/ F9BF E0C2 480E 7680 1AE5 3631 CB32 A107 88C3 A5A5 Q: It is impossible to make anything foolproof because fools are so ingenious. perl -e'$$=\${gozer};{$_=unpack(P7,pack(L,$$));/^JAm_pH\n$/&&print||$$++&&redo}'
I've attached a patch for Apache::Reload that makes use of your code to >>achieve what I'm after. The patch is against the Apache::Reload >>currently in mp2 cvs. Things to note:>>
And integrate that into an mod_perl 1 & 2 Apache::Reload instead? I>would rather not have to maintain 2 ever so slightly different versions>of Apache::Reload if that can be avoided.>
Done. Attached.
I had to alter the patch that you cited above very slightly: it defers the import of the OK constant until run-time, which made it choke on the bareword OK (since its running under "use strict"). I've therefore pushed the mp1/mp2 conditional stuff inside a BEGIN {} block.
I've also added a couple of extra lines to conditionally setup an undef_func() -- under mp1 it is just Apache::Symbol::undef, under mp2 it will be ModPerl::Util::undef which you suggested in the rest of your mail (below).
The only other thing that I was using from Apache::Symbol was the file2class() function. I've now included that in Apache::Reload itself as module_to_package(), complementing the package_to_module() that it already had.
So there is no need to put Apache::Symbol back into mp2 -- just copy its undef() to ModPerl::Util as you suggested, and hopefully this Apache::Reload will work with mp1 and mp2.
I've re-tested it under mp1 and it still looks OK. I don't have an mp2 system to try out, though.
Steve
I've quickly tested this mp1-compatible version, and it seems to be >>working so far: no "subroutine redefined" warnings are being produced >>(not even for constant subroutines), and imported subroutines are not >>being mistakenly undefined. I hope this can be added to mp1.28 (which >>already has Apache::Symbol, of course).>>
Just might >
I guess Apache::Symbol might need to be re-created for mp2. According>to :>$> fgrep Apache::Symbpl mp2/docs/deprecated_features.txt> + Apache::Symbol: unknown>
There are only 3 functions in there, and they are:>undef>sv_name>cv_const_sv>
I don't see why we can't find some room for those somewhere in mp2,>especially the magical 'undef' function in there.>
Stas: BTW, for Apache::Reload, to get rid of that constant subroutine>redefined, that XS implemtation would get rid of it without a need for>skip_redefine_const_sub_warn. No more $SIG{__WARN__} >
How about if I ported Apache::Symbol::undef to ModPerl::Util::undef ?>
Gozer out to bed.>
--- Reload.pm.orig2003-06-17 08:37:04.000000000 +0100 +++ Reload.pm2003-06-18 17:39:26.000000000 +0100 @@ -3,15 +3,32 @@ use strict; use warnings FATAL => 'all';
@@ -144,9 +167,10 @@ no strict 'refs'; undef %{$symref}; } - no warnings FATAL => 'all'; - local $SIG{__WARN__} = \&skip_redefine_const_sub_warn - unless $ConstantRedefineWarnings; + if ($RemovePackageOnReload) { + my $pkg = module_to_package($key); + remove_package($pkg); + } require $key; warn("Apache::Reload: process $$ reloading $key\n") if $DEBUG; @@ -154,12 +178,101 @@ $Stat{$file} = $mtime; }
- return Apache::OK; + return OK; +} + +sub remove_package { + my $package = shift; + my $recursive = shift || 0; + my $create = $recursive ? 'rnew' : 'new'; + + my @removed; + + if ($package eq __PACKAGE__ || $package =~ /^(B|Devel)::/) { + # suicide ? I don't think so... + # we do not attempt to reload ourselves, or B and Devel packages + return; + } + + # should be a more safe way to figure it out than this + if ($package->can('bootstrap')) { + # XS/C code, very bad for now ! BAIL out + warn "$package contains non-perl code and can't be reloaded for now\n"; + return; + } + + my $stab = Devel::Symdump->$create($package); + + my @methods = grep {$_ !~ /^(packages|ios|functions)$/} + sort keys %{$stab->{AUTOLOAD}}; + + for my $type ('packages', 'ios', @methods, 'functions') { + (my $dtype = uc $type) =~ s/E?S$//; + + for (sort $stab->_partdump(uc $type)) { + s/([\000-\037\177])/ '^' . pack('c',ord($1) ^ 64)/eg; + next if /::SUPER(::.*)?$/; + + if ($type eq 'scalars') { + no strict 'refs'; + next unless defined $$_; + } + elsif ($type eq 'packages') { + next unless $recursive; + push @removed, remove_package($_, 'recursive'); + } + elsif ($type eq 'functions') { + no strict 'refs'; + my $stash = B::svref_2object(*$_{CODE})->GV->STASH->NAME; + # don't undef functions that are imported into this package + # from elsewhere + next if $stash ne $package; + } + + no strict 'refs'; + &{"undef_$dtype"} ($_) if defined &{"undef_$dtype"}; + } + } + + push @removed, $package; + + my $filename = package_to_module($package); + delete $INC{$filename}; + +# warn "UNLOADING OF $package COMPLETE\n"; + return @removed; +} + +sub undef_IO { + my $name = shift; + no strict 'refs'; + # don't test if *$name is tied() first - see RT/perl ticket #9725 + untie *$name; + close *$name; }
-sub skip_redefine_const_sub_warn { - return if $_[0] =~ /^Constant subroutine [\w:]+ redefined at/; - CORE::warn(@_); +sub undef_FUNCTION { + my $name = shift; + no strict 'refs'; + undef_func(*{$name}{CODE}); +} + +sub undef_SCALAR { + my $name = shift; + no strict 'refs'; + undef $$name; +} + +sub undef_ARRAY { + my $name = shift; + no strict 'refs'; + undef $$name; +} + +sub undef_HASH { + my $name = shift; + no strict 'refs'; + undef $$name; }
1;
--------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org For additional commands, e-mail: dev-help@perl.apache.org
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. >>>