|
|
Choosing A Webhost: |
[mp2 patch] introducing Apache::compat "scoping": msg#00136apache.mod-perl.devel
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.pm 19 Nov 2003 19:30:11 -0000 1.90 +++ lib/Apache/compat.pm 15 Dec 2003 02:02:10 -0000 @@ -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 register_cleanup { shift->pool->cleanup_register(@_); @@ -345,12 +416,6 @@ sub chdir_file { #XXX resolve '.' in @INC to basename $r->filename -} - -sub finfo { - my $r = shift; - stat $r->filename; - \*_; } *log_reason = \&log_error; Index: t/response/TestCompat/request.pm =================================================================== RCS file: /home/cvs/modperl-2.0/t/response/TestCompat/request.pm,v retrieving revision 1.3 diff -u -r1.3 request.pm --- t/response/TestCompat/request.pm 11 Apr 2003 07:34:03 -0000 1.3 +++ t/response/TestCompat/request.pm 15 Dec 2003 02:02:10 -0000 @@ -75,6 +75,8 @@ # $r->notes { + Apache::compat::override_mp2_api('Apache::RequestRec::notes'); + my $key = 'notes-test'; # get/set scalar context { @@ -98,6 +100,10 @@ $r->notes->add($key => $_) for @exp; ok t_cmp(\@exp, [ $r->notes($key) ], "\$r->notes in list context"); } + + # restore the real 2.0 notes() method, now that we are done + # with the compat one + Apache::compat::restore_mp2_api('Apache::RequestRec::notes'); } # get_remote_host() __________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:stas@xxxxxxxxxx http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
|
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | Re: [mp2] mod_perl test suite fails, Stas Bekman |
|---|---|
| Next by Date: | mp2-1.99_12 release next week?, Stas Bekman |
| Previous by Thread: | fyi: mod_perl cvs OK on osx 10.3.1 w/ apache2 2.1.0 head, OpenMacNews |
| Next by Thread: | Re: [mp2 patch] introducing Apache::compat "scoping", Philippe M. Chiasson |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
Free MagazinesCisco NewsReceive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business. subscribe Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field. subscribe The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business. subscribe Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company. subscribe Total Telecom Total Telecom is "The Economist of the communications industry". subscribe |