[prev in list] [next in list] [prev in thread] [next in thread]
List: apache-modperl
Subject: Re: getting rid of nested sub lexical problem
From: Chris Nokleberg <cjn () rock ! pickem ! com>
Date: 2000-12-30 10:08:30
[Download RAW message or body]
On Thu, 21 Dec 2000, Doug MacEachern wrote:
> On Thu, 19 Oct 2000, Chris Nokleberg wrote:
>
> > Following up on my post on this subject a couple of months ago, here is a
> > proof-of-concept drop-in replacement for Apache::Registry that eliminates
> > the "my() Scoped Variable in Nested Subroutine" problem.
>
> nice hack!
>
> > It requires PERL5OPT = "-d" and PERL5DB = "sub DB::DB {}" environment
> > variables set when starting the mod_perl-enabled httpd. This enables the
> > %DB::sub hash table that holds subroutine start and end line info. I
> > presume that this has some negative (marginal?) impact on performance. If
> > someone knows of a better way to reliably figure out where a subroutine
> > starts and ends, please let me know.
>
> there is quite a bit of overhead when -d is enabled. have a look at
> Apache::DB.xs, there's in init_debugger() function todo what -d does. if
> another method was added to turn it off, after the registry script was
> compiled, the overhead would be reduced a great deal.
oooh, cool. I've added this to Apache::DB.xs:
int
stop_debugger()
CODE:
if (PL_perldb) {
PL_perldb = 0;
RETVAL = TRUE;
}
else
RETVAL = FALSE;
OUTPUT:
RETVAL
It appears that setting PL_perldb to zero is all that's required to turn
off the debugger! I thought I might have to fiddle with the symbol tables
but this seems to work.
I've attached the latest version of Apache::NiceRegistry (suggestions
welcome) below. Not sure this is the right thing to do , but I call
Apache::DB::init_debugger directly because I need the return value (don't
want to stop_debugger if it was turned on outside of this handler), and I
don't want the warning that Apache::DB->init produces.
Also, why does Apache::DB unset $Apache::Registry::MarkLine?
Thanks,
Chris
--------------------------------------
package Apache::NiceRegistry;
use base Apache::RegistryNG;
use strict;
use Apache::DB ();
$Apache::Registry::MarkLine = 1;
my %skip_subs = map { $_ => 1 } qw( handler BEGIN END CHECK INIT );
sub compile {
my ($pr, $eval) = @_;
$eval ||= $pr->{'sub'};
my $init_db = Apache::DB::init_debugger();
$pr->SUPER::compile($eval);
Apache::DB::stop_debugger() if $init_db;
my $package = $pr->namespace;
my @lines = split /\n/, $$eval;
foreach my $sub (grep /^$\Qpackage\E/, keys %DB::sub) {
my ($name) = $sub =~ /:([^:]+)$/;
next if $skip_subs{$name};
my ($start, $end) = $DB::sub{$sub} =~ /:(\d+)-(\d+)$/;
$lines[$start + 1] =~ s:(sub[^\{]+\{):$1&\{sub\{:;
$lines[$end + 1] =~ s:\}(?!.*\})$:\}\}\}:;
}
$$eval = join "\n", @lines;
$pr->flush_namespace($package);
$pr->SUPER::compile($eval);
}
1;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic