The following is yet another attempt to avoid collisions between
Apache::compat and the real mp2 APIs.
Similar to 'use' and 'no' pragma, I'm suggesting to introduce the new
functions override_mp2_api and restore_mp2_api for those APIs in
Apache::compat that collide with 2.0 API. The only difference is that one
needs an explicit call to restore_mp2_api, which I suppose could be done by
returning an object, which if made a lexically scoped will call
restore_mp2_api on its own (i.e. DESTROY), but since it's going to be used
very infrequently and eventually won't be needed at all, I don't see a reason
to bother. See the compat/request test change for an example in the patch below.
I decided not to use the import() method, but have an explicit function call,
since import() may make some people think that it imports the overriden
methods, which it doesn't.
I think there are only two functions at the moment that collide with mp2 API:
Apache::RequestRec::notes and Apache::RequestRec::finfo. There is also
APR::URI::unparse, which introduces a special case but I think it's harmless.
in June I posted an implementation for 2 more colliding functions:
Apache::Connection::local_addr
Apache::Connection::remote_addr
http://marc.theaimsgroup.com/?l=apache-modperl-dev&m=105452446932154&w=2
which I will now be able to commit using this new functionality.
The cool thing is that we can introduce a sub-class of Registry which will do
the wrapping into a handler like so:
'sub handler {' .
'Apache::compat::override_mp2_api('Apache::RequestRec::notes');' .
$code .
'Apache::compat::restore_mp2_api('Apache::RequestRec::notes');' .
'}';
or something like that (overriding other subs as well).
Here is the patch:
Index: lib/Apache/compat.pm
===
RCS file: /home/cvs/modperl-2.0/lib/Apache/compat.pm,v
retrieving revision 1.90
diff -u -r1.90 compat.pm
--- lib/Apache/compat.pm19 Nov 2003 19:30:11 - 1.90
+++ lib/Apache/compat.pm15 Dec 2003 02:02:10 -
@@ -50,6 +50,86 @@
$INC{'Apache/Table.pm'} = __FILE__;
}
+# api => "overriding code"
+# the overriding code, needs to "return" the original CODE reference
+# when eval'ed , so that it can be restored later
+my %overridable_mp2_api = (
+'Apache::RequestRec::notes' => <<'EOI',
+{
+require Apache::RequestRec;
+my $notes_sub = *Apache::RequestRec::notes{CODE};
+*Apache::RequestRec::notes = sub {
+my $r = shift;
+return wantarray()
+? ($r->table_get_set(scalar($r->$notes_sub), @_))
+: scalar($r->table_get_set(scalar($r->$notes_sub), @_));
+};
+$notes_sub;
+}
+EOI
+
+'Apache::RequestRec::finfo' => <<'EOI',
+{
+require APR::Finfo;
+my $finfo_sub = *APR::Finfo::finfo{CODE};
+sub Apache::RequestRec::finfo {
+my $r = shift;
+stat $r->filename;
+\*_;
+}
+$finfo_sub;
+}
+EOI
+);
+
+my %overridden_mp2_api = ();
+
+# this function enables back-compatible APIs which can't coexist with
+# mod_perl 2.0 APIs with the same name and therefore it should be
+# avoided if possible.
+#
+# it expects a list of fully qualified functions, like
+# "Apache::RequestRec::finfo"
+sub override_mp2_api {
+my (@subs) = @_;
+
+for my $sub (@subs) {
+unless (exists $overridable_mp2_api{$sub}) {
+die __PACKAGE__ . ": $sub is not overridable";
+}
+if(exists $overridden_mp2_api{$sub}) {
+warn __PACKAGE__ . ": $sub has been already overridden";
+next;
+}
+$overridden_mp2_api{$sub} = eval $overridable_mp2_api{$sub};
+unless (exists $overridden_mp2_api{$sub} &&
+ref($overridden_mp2_api{$sub}) eq 'CODE') {
+die "overriding $sub didn't return a CODE ref";
+}
+}
+}
+
+# restore_mp2_api does the opposite of override_mp2_api(), it removes
+# the overriden API and restores the original mod_perl 2.0 API
+sub restore_mp2_api {
+my (@subs) = @_;
+
+for my $sub (@subs) {
+unless (exists $overridable_mp2_api{$sub}) {
+die __PACKAGE__ . ": $sub is not overridable";
+}
+unless (exists $overridden_mp2_api{$sub}) {
+warn __PACKAGE__ . ": can't restore $sub, " .
+"as it has not been overridden";
+next;
+}
+my $original_sub = delete $overridden_mp2_api{$sub};
+no warnings 'redefine';
+no strict 'refs';
+*$sub = $original_sub;
+}
+}
+
sub request {
my $what = shift;
@@ -249,15 +329,6 @@
: scalar($r->table_get_set(scalar($r->err_headers_out), @_));
}
-{
-my $notes_sub = *Apache::RequestRec::notes{CODE};
-*Apache::RequestRec::notes = sub {
-my $r = shift;
-return wantarray()
-? ($r->table_get_set(scalar($r->$notes_sub), @_))
-: scalar($r->table_get_set(scalar($r->$notes_sub), @_));
-}
-}
sub