You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@perl.apache.org by "Philippe M. Chiasson" <go...@cpan.org> on 2002/09/25 18:06:17 UTC

[Patch] Default Handler and a wee bit more

Alright, following my last conversation with Doug last week, I have
changed a few things in order to get <Perl> sections up and running. 

First, I wrote a default pure perl handler that seems to behave just
like the old <Perl> sections: Apache::PerlSection. 

In my early tests, the fact that <Perl> sections were parsed by apache
became quite problematic, as all sort of perl constructs would trip off
the parser and throw a syntax error.... 

So, this patch makes <Perl> blocks EXEC_ON_READ, completely avoiding the
parser and reading the content of the block ourselves. But, at that
point, it's way to early to do anything with the code. So, I just store
it for later and alter the ap_conftree just a bit so that the <Perl>
section is replaced by a Perl directive to be processed when walking the
configuration tree later. 

With a Perl directive, in httpd.conf you could do 

Perl print "Hello world!\n"; 

And that would work as expected. So, say you have a block like this: 

<Perl> 
$ServerAdmin = 'foo@bar.com'; 
</Perl> 

it's parsed and rewritten like this : 

Perl package Apache::ReadConfig; $ServerAdmin = 'foo@bar.com'; 

When processing the content of a Perl line, there is a difference from a
textual Perl print "hello"; and one line constructed from a <Perl>
block. The difference is that for <Perl> sections, after the code is
run, a handler is called to do something with that code.
Apache::PerlSection is just the default, but you could do 

<Perl handler=My::Handler package=Some::Package>[...]</Perl> 

CAVEATS: 

1. the Perl directive must be RAW_ARGS, so that simply doesn't try to
parse the arguments of the directive. 
2. when using modperl_handler_make_args, it's a bit too generic and
generates an untied APR::Table object $args->get("package") 
3. The necessity to have all PerlSwitches and so on before the first
<Perl> section makes writing tests quite messy (see
lib/ModPerl/TestRun.pm) 
4. Backward compatibility needs some testing 

Tested with : 
------------- 
Perl 5.8.0 & perl@17850 
httpd 2.0.42(perfork/leader/worker) 


--- /dev/null	Thu Apr 11 22:25:15 2002
+++ lib/Apache/PerlSection.pm	Wed Sep 25 23:52:08 2002
@@ -0,0 +1,154 @@
+package Apache::PerlSection;
+
+use strict;
+use warnings FATAL => 'all';
+
+our $VERSION = '0.01';
+
+use Devel::Symdump qw();
+
+require Apache::CmdParms;
+require Apache::Directive;
+
+use constant SPECIAL_NAME => 'PerlConfig';
+
+sub new {
+    my ( $package, @args ) = @_;
+    return bless { @args }, ref($package) || $package;
+}
+
+sub server     { return shift->{'parms'}->server() }
+sub directives { return shift->{'directives'} ||= [] }
+
+sub handler : method {
+    my ( $self, $parms, $args ) = @_;
+
+    unless (ref($self)) { 
+		$self = $self->new( 'parms' => $parms, 'args' => $args );
+	}
+
+    my $package = $args->get('package');
+    my $special = $self->SPECIAL_NAME;
+	
+    my $root = new Devel::Symdump $package;
+
+    my %convert = (
+        'scalars' => sub { no strict 'refs'; return ${ $_[0] } },
+        'arrays'  => sub { no strict 'refs'; return \@{ $_[0] } },
+        'hashes'  => sub { no strict 'refs'; return \%{ $_[0] } },
+    );
+
+    foreach my $type ( sort keys %convert ) {
+        foreach my $entry ( grep { !/$special/ } $root->$type() ) {
+            ( my $name = $entry ) =~ s/${package}:://;
+            $self->dump( $name, $convert{$type}->($entry) );
+        }
+    }
+
+    {
+        no strict 'refs';
+        $self->dump_special( ${"${package}::$special"},
+            @{"${package}::$special"} );
+    }
+
+    $self->post_config();
+
+    Apache::OK;
+}
+
+sub dump_special {
+    my ( $self, @data ) = @_;
+    $self->add_config(@data);
+}
+
+sub dump {
+    my ( $self, $name, $entry ) = @_;
+    my $type = ref($entry);
+
+    if ( 'ARRAY' eq $type ) {
+        $self->dump_array( $name, $entry );
+    }
+    elsif ( 'HASH' eq $type ) {
+        $self->dump_hash( $name, $entry );
+    }
+    else {
+        $self->dump_entry( $name, $entry );
+    }
+}
+
+sub dump_hash {
+    my ( $self, $name, $hash ) = @_;
+    foreach my $entry ( sort keys %{ $hash || {} } ) {
+        my $item = $hash->{$entry};
+        my $type = ref($item);
+
+        if ( 'HASH' eq $type ) {
+            $self->dump_section( $name, $entry, $item );
+        }
+        elsif ( 'ARRAY' eq $type ) {
+            foreach my $e (@$item) {
+                $self->dump_section( $name, $entry, $e );
+            }
+        }
+
+    }
+}
+
+sub dump_section {
+    my ( $self, $name, $loc, $hash ) = @_;
+
+    $self->add_config("<$name $loc>\n");
+
+    foreach my $entry ( sort keys %{ $hash || {} } ) {
+        $self->dump_entry( $entry, $hash->{$entry} );
+    }
+
+    $self->add_config("</$name>\n");
+}
+
+sub dump_array {
+    my ( $self, $name, $entries ) = @_;
+
+    foreach my $entry (@$entries) {
+        $self->dump_entry( $name, $entry );
+    }
+}
+
+sub dump_entry {
+    my ( $self, $name, $entry ) = @_;
+    my $type = ref($entry);
+
+    if ( 'SCALAR' eq $type ) {
+        $self->add_config("$name $$entry\n");
+    }
+    elsif ( 'ARRAY' eq $type ) {
+        $self->add_config("$name @$entry\n");
+    }
+    elsif ( 'HASH' eq $type ) {
+        $self->dump_hash( $name, $entry );
+    }
+    elsif ($type) {
+
+        #XXX: Could do $type->can('httpd_config') here on objects ???
+        die "Unknown type '$type' for directive $name";
+    }
+    elsif ( defined $entry ) {
+        $self->add_config("$name $entry\n");
+    }
+}
+
+sub add_config {
+    my ( $self, $config ) = @_;
+    return unless defined $config;
+    chomp($config);
+    push @{ $self->directives }, $config;
+}
+
+sub post_config {
+    my ($self) = @_;
+    my $errmsg = $self->server->add_config( $self->directives );
+    die $errmsg if $errmsg;
+}
+
+1;
+__END__

--- /dev/null	Thu Apr 11 22:25:15 2002
+++ t/response/TestDirective/perldo.pm	Wed Sep 25 23:52:08 2002
@@ -0,0 +1,20 @@
+package TestDirective::perldo;
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::Const -compile => 'OK';
+
+sub handler {
+    my $r = shift;
+
+    plan $r, tests => 1;
+
+    ok t_cmp('yes', $TestDirective::perl::worked);
+
+    Apache::OK;
+}
+
+1;

Index: STATUS
===================================================================
RCS file: /home/cvspublic/modperl-2.0/STATUS,v
retrieving revision 1.12
diff -u -b -B -r1.12 STATUS
--- STATUS	17 Sep 2002 02:46:20 -0000	1.12
+++ STATUS	25 Sep 2002 15:59:04 -0000
@@ -54,10 +54,6 @@
 Needs Patch or Further Investigation:
 -------------------------------------
 
-* pluggable <Perl> sections have been implemented but need a default
-  handler to actually convert the Perl code into apache config
-  [Philippe M. Chiasson <go...@cpan.org> is working on one]
-
 * Apache->httpd_conf compat method mapping to Apache::Server->add_config
 
 * directive handlers are supported but need some work for 1.x compat

Index: lib/ModPerl/TestRun.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/lib/ModPerl/TestRun.pm,v
retrieving revision 1.3
diff -u -b -B -r1.3 TestRun.pm
--- lib/ModPerl/TestRun.pm	27 Aug 2002 04:31:55 -0000	1.3
+++ lib/ModPerl/TestRun.pm	25 Sep 2002 15:59:06 -0000
@@ -30,9 +30,16 @@
     #XXX: issue for these is they need to happen after PerlSwitches
 
     #XXX: this should only be done for the modperl-2.0 tests
-    $self->postamble(<<'EOF');
-<Perl handler=ModPerl::Test::perl_section>
-    $Foo = 'bar';
+    my $htdocs = $self->{vars}{documentroot};
+    $self->postamble(<<"EOF");
+<Perl >
+push \@Alias, ['/perl_sections', '$htdocs'],
+\$Location{'/perl_sections'} = {
+	'PerlInitHandler' => 'ModPerl::Test::add_config',
+	'AuthType' => 'Basic',
+	'AuthName' => 'PerlSection',
+	'PerlAuthenHandler' => 'TestHooks::authen',
+	};
 </Perl>
 EOF
 
@@ -46,6 +53,11 @@
 <Location /TestDirective::loadmodule>
     MyOtherTest value
 </Location>
+EOF
+
+	#XXX: this should only be done for the modperl-2.0 tests
+	$self->postamble(<<'EOF');
+	Perl $TestDirective::perl::worked="yes";
 EOF
 }
 

Index: src/modules/perl/mod_perl.c
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/mod_perl.c,v
retrieving revision 1.141
diff -u -b -B -r1.141 mod_perl.c
--- src/modules/perl/mod_perl.c	17 Sep 2002 02:05:21 -0000	1.141
+++ src/modules/perl/mod_perl.c	25 Sep 2002 15:59:08 -0000
@@ -629,7 +629,8 @@
     MP_CMD_DIR_ITERATE2("PerlAddVar", add_var, "PerlAddVar"),
     MP_CMD_DIR_TAKE2("PerlSetEnv", set_env, "PerlSetEnv"),
     MP_CMD_SRV_TAKE1("PerlPassEnv", pass_env, "PerlPassEnv"),
-    MP_CMD_SRV_RAW_ARGS("<Perl", perl, "NOT YET IMPLEMENTED"),
+    MP_CMD_SRV_RAW_ARGS_ON_READ("<Perl", perl, "Perl Code"),
+    MP_CMD_SRV_RAW_ARGS("Perl", perldo, "Perl Code"),
 	
     MP_CMD_DIR_RAW_ARGS_ON_READ("=pod", pod, "Start of POD"),
     MP_CMD_DIR_RAW_ARGS_ON_READ("=back", pod, "End of =over"),

Index: src/modules/perl/modperl_cmd.c
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/modperl_cmd.c,v
retrieving revision 1.30
diff -u -b -B -r1.30 modperl_cmd.c
--- src/modules/perl/modperl_cmd.c	16 Sep 2002 19:14:16 -0000	1.30
+++ src/modules/perl/modperl_cmd.c	25 Sep 2002 15:59:10 -0000
@@ -245,26 +245,24 @@
     return modperl_cmd_post_read_request_handlers(parms, mconfig, arg);
 }
 
-static const char *modperl_cmd_parse_args(pTHX_ apr_pool_t *p,
+static const char *modperl_cmd_parse_args(apr_pool_t *p,
                                           const char *args,
-                                          HV **hv)
+                                          apr_table_t **t)
 {
     const char *orig_args = args;
     char *pair, *key, *val;
-    *hv = newHV();
+    *t = apr_table_make(p, 2);
 
     while (*(pair = ap_getword(p, &args, ',')) != '\0') {
         key = ap_getword_nc(p, &pair, '=');
         val = pair;
 
         if (!(*key && *val)) {
-            SvREFCNT_dec(*hv);
-            *hv = Nullhv;
             return apr_pstrcat(p, "invalid args spec: ",
                                orig_args, NULL);
         }
 
-        hv_store(*hv, key, strlen(key), newSVpv(val,0), 0);
+        apr_table_set(*t, key, val);
     }
 
     return NULL;
@@ -273,21 +271,67 @@
 MP_CMD_SRV_DECLARE(perl)
 {
     apr_pool_t *p = parms->pool;
-    server_rec *s = parms->server;
     const char *endp = ap_strrchr_c(arg, '>');
     const char *errmsg;
-    modperl_handler_t *handler;
-    AV *args = Nullav;
-    HV *hv = Nullhv;
-    SV **handler_name;
+    char *code = "";
+    char line[MAX_STRING_LEN];
+    apr_table_t *args;
+    ap_directive_t **current = mconfig;
+
+    if (endp == NULL) {
+        return modperl_cmd_unclosed_directive(parms);
+    }
+
+    arg = apr_pstrndup(p, arg, endp - arg);
+   
+    if ((errmsg = modperl_cmd_parse_args(p, arg, &args))) {
+        return errmsg;
+    }
+
+    while (!ap_cfg_getline(line, sizeof(line), parms->config_file)) {
+        /*XXX: Not sure how robust this is */
+        if (strEQ(line, "</Perl>")) {
+            break;
+        }
+        
+        /*XXX: Less than optimal */
+        code = apr_pstrcat(p, code, line, NULL);
+    }
+    
+    /* Here, we have to replace our current config node for the next pass */
+    if(!*current) {
+        *current = apr_pcalloc(p, sizeof(ap_directive_t));
+    }
+    
+    (*current)->filename = parms->config_file->name;
+    (*current)->line_num = parms->config_file->line_number;
+    (*current)->directive = apr_pstrdup(p,"Perl");
+    (*current)->args = code;
+    (*current)->data = args;
+
+    return NULL;
+}
+
+#define MP_DEFAULT_PERLSECTION_HANDLER "Apache::PerlSection"
+#define MP_DEFAULT_PERLSECTION_PACKAGE "Apache::ReadConfig"
+
+MP_CMD_SRV_DECLARE(perldo)
+{
+    apr_pool_t *p = parms->pool;
+    server_rec *s = parms->server;
+    apr_table_t *options = NULL;
+    const char *handler_name = NULL;
+    modperl_handler_t *handler = NULL;
+    const char *package_name = NULL;
     int status = OK;
+    AV *args = Nullav;
 #ifdef USE_ITHREADS
     MP_dSCFG(s);
     pTHX;
 #endif
 
-    if (endp == NULL) {
-        return modperl_cmd_unclosed_directive(parms);
+    if( !(arg && (*arg)) ) {
+        return NULL;
     }
 
     /* we must init earlier than normal */
@@ -302,22 +346,37 @@
     aTHX = scfg->mip->parent->perl;
 #endif
 
-    arg = apr_pstrndup(p, arg, endp - arg);
+    /* data will be set by a <Perl> section */
+    if ( (options = parms->directive->data) ) {
 
-    if ((errmsg = modperl_cmd_parse_args(aTHX_ p, arg, &hv))) {
-        return errmsg;
+        if( !(handler_name = apr_table_get(options,"handler")) ) {
+            handler_name = apr_pstrdup(p,  MP_DEFAULT_PERLSECTION_HANDLER);
+            apr_table_set(options, "handler", handler_name);
+        }
+        
+        handler = modperl_handler_new(p, handler_name);
+            
+        if( !(package_name = apr_table_get(options,"package")) ) {
+            package_name = apr_pstrdup(p,  MP_DEFAULT_PERLSECTION_PACKAGE);
+            apr_table_set(options, "package", package_name);
     }
 
-    if (!(handler_name = hv_fetch(hv, "handler", strlen("handler"), 0))) {
-        /* XXX: we will have a default handler in the future */
-        return "no <Perl> handler specified";
+        /* put the code about to be executed in the configured package */
+        arg = apr_pstrcat(p, "package ", package_name , ";", arg, NULL);
     }
 
-    handler = modperl_handler_new(p, SvPVX(*handler_name));
+    eval_pv(arg, FALSE);
 
+    if SvTRUE(ERRSV) {
+        return SvPVX(ERRSV);
+    }
+    
+    if(handler) {
+        
+    /*XXX: This will return a blessed APR::Table, but not a tied one ;-( */ 
     modperl_handler_make_args(aTHX_ &args,
                               "Apache::CmdParms", parms,
-                              "HV", hv,
+                                  "APR::Table", options,
                               NULL);
 
     status = modperl_callback(aTHX_ handler, p, NULL, s, args);
@@ -328,6 +387,7 @@
         return SvTRUE(ERRSV) ? SvPVX(ERRSV) :
             apr_psprintf(p, "<Perl> handler %s failed with status=%d",
                          handler->name, status);
+        }
     }
 
     return NULL;

Index: src/modules/perl/modperl_cmd.h
===================================================================
RCS file: /home/cvspublic/modperl-2.0/src/modules/perl/modperl_cmd.h,v
retrieving revision 1.19
diff -u -b -B -r1.19 modperl_cmd.h
--- src/modules/perl/modperl_cmd.h	16 Sep 2002 19:14:16 -0000	1.19
+++ src/modules/perl/modperl_cmd.h	25 Sep 2002 15:59:12 -0000
@@ -27,6 +27,7 @@
 MP_CMD_SRV_DECLARE(options);
 MP_CMD_SRV_DECLARE(init_handlers);
 MP_CMD_SRV_DECLARE(perl);
+MP_CMD_SRV_DECLARE(perldo);
 MP_CMD_SRV_DECLARE(pod);
 MP_CMD_SRV_DECLARE(pod_cut);
 MP_CMD_SRV_DECLARE(END);
@@ -69,6 +70,10 @@
 #define MP_CMD_SRV_RAW_ARGS(name, item, desc) \
     AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \
       RSRC_CONF, desc )
+
+#define MP_CMD_SRV_RAW_ARGS_ON_READ(name, item, desc) \
+    AP_INIT_RAW_ARGS( name, modperl_cmd_##item, NULL, \
+      RSRC_CONF|EXEC_ON_READ, desc )
 
 #define MP_CMD_SRV_FLAG(name, item, desc) \
     AP_INIT_FLAG( name, modperl_cmd_##item, NULL, \

Index: t/conf/modperl_extra.pl
===================================================================
RCS file: /home/cvspublic/modperl-2.0/t/conf/modperl_extra.pl,v
retrieving revision 1.19
diff -u -b -B -r1.19 modperl_extra.pl
--- t/conf/modperl_extra.pl	5 Sep 2002 01:49:32 -0000	1.19
+++ t/conf/modperl_extra.pl	25 Sep 2002 15:59:14 -0000
@@ -72,43 +72,6 @@
     Apache::OK;
 }
 
-#<Perl handler=ModPerl::Test::perl_section>
-# ...
-#</Perl>
-sub ModPerl::Test::perl_section {
-    my($parms, $args) = @_;
-
-    require Apache::CmdParms;
-    require Apache::Directive;
-
-    my $code = $parms->directive->as_string;
-    my $package = $args->{package} || 'Apache::ReadConfig';
-
-##   a real handler would do something like:
-#    eval "package $package; $code";
-#    die $@ if $@;
-##   feed %Apache::ReadConfig:: to Apache::Server->add_config
-
-    my $htdocs = Apache::server_root_relative($parms->pool, 'htdocs');
-
-    my @cfg = (
-       "Alias /perl_sections $htdocs",
-       "<Location /perl_sections>",
-#       "   require valid-user",
-       "   PerlInitHandler ModPerl::Test::add_config",
-       "   AuthType Basic",
-       "   AuthName PerlSection",
-       "   PerlAuthenHandler TestHooks::authen",
-       "</Location>",
-    );
-
-    my $errmsg = $parms->server->add_config(\@cfg);
-
-    die $errmsg if $errmsg;
-
-    Apache::OK;
-}
-
 END {
     warn "END in modperl_extra.pl, pid=$$\n";
 }

Index: t/directive/.cvsignore
===================================================================
RCS file: /home/cvspublic/modperl-2.0/t/directive/.cvsignore,v
retrieving revision 1.2
diff -u -b -B -r1.2 .cvsignore
--- t/directive/.cvsignore	16 Sep 2002 19:14:17 -0000	1.2
+++ t/directive/.cvsignore	25 Sep 2002 15:59:16 -0000
@@ -1,3 +1,4 @@
 env.t
 loadmodule.t
 pod.t
+perldo.t

Index: todo/possible_new_features.txt
===================================================================
RCS file: /home/cvspublic/modperl-2.0/todo/possible_new_features.txt,v
retrieving revision 1.13
diff -u -b -B -r1.13 possible_new_features.txt
--- todo/possible_new_features.txt	9 Apr 2002 07:32:56 -0000	1.13
+++ todo/possible_new_features.txt	25 Sep 2002 15:59:18 -0000
@@ -14,12 +14,6 @@
 - allow <Perl></Perl> configuration sections to have read access to internal
   configuration structures (would be nice if we could tie a %namespace::) 
 
-- allow things like <Perl main> -- the code will be placed into 'main'
-  package. Of course any package can be specified and the default is
-  Apache::ReadConfig. That would place a little meme-fleck into
-  people's brains to remind them that the default package is
-  Apache::ReadConfig.
-
 - setuid/gid before running any Perl code
 
 - implement PerlINC (or similar) as a nicer interface for the working





---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Re: [Patch] Apache::PerlSections witout Devel::Symdump

Posted by Doug MacEachern <do...@covalent.net>.
On 7 Oct 2002, Philippe M. Chiasson wrote:
 
> Here it is, stripped down of Devel::Symdump, and it actually makes the
> main loop a bit clearer.

very nice, thanks.



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


[Patch] Apache::PerlSections witout Devel::Symdump

Posted by "Philippe M. Chiasson" <go...@cpan.org>.
On Mon, 2002-10-07 at 10:29, Doug MacEachern wrote:
> excellent work Philippe!!  thanks, i've applied your patch.
> one change i made was to remove the dependency on Devel::Symdump by simply 
> making a copy of it into ModPerl::Symdump.  would happily apply patches 
> that prune away the things we don't need there for Apache::PerlSection, 
> such as inh_tree, etc.

Here it is, stripped down of Devel::Symdump, and it actually makes the
main loop a bit clearer.

Index: lib/Apache/PerlSection.pm
===================================================================
RCS file: /home/cvspublic/modperl-2.0/lib/Apache/PerlSection.pm,v
retrieving revision 1.1
diff -u -I'$Id' -I'$Revision' -r1.1 PerlSection.pm
--- lib/Apache/PerlSection.pm   7 Oct 2002 02:35:18 -0000       1.1
+++ lib/Apache/PerlSection.pm   7 Oct 2002 04:04:29 -0000
@@ -5,7 +5,6 @@
 
 our $VERSION = '0.01';
 
-use ModPerl::Symdump ();
 
 use Apache::CmdParms ();
 use Apache::Directive ();
@@ -19,6 +18,7 @@
 
 sub server     { return shift->{'parms'}->server() }
 sub directives { return shift->{'directives'} ||= [] }
+sub package    { return shift->{'args'}->get('package') }
 
 sub handler : method {
     my($self, $parms, $args) = @_;
@@ -27,25 +27,17 @@
         $self = $self->new('parms' => $parms, 'args' => $args);
     }
 
-    my $package = $args->get('package');
     my $special = $self->SPECIAL_NAME;
        
-    my $root = ModPerl::Symdump->new($package);
-
-    my %convert = (
-        'scalars' => sub { no strict 'refs'; return ${ $_[0] } },
-        'arrays'  => sub { no strict 'refs'; return \@{ $_[0] } },
-        'hashes'  => sub { no strict 'refs'; return \%{ $_[0] } },
-    );
-
-    for my $type (sort keys %convert) {
-        for my $entry (grep { !/$special/ } $root->$type()) {
-            (my $name = $entry) =~ s/${package}:://;
-            $self->dump($name, $convert{$type}->($entry));
+    for my $entry ($self->symdump())
+    {
+        if ($entry->[0] !~ /$special/) {
+            $self->dump(@$entry);
         }
     }
 
     {
+        my $package = $self->package;
         no strict 'refs';
         $self->dump_special(${"${package}::$special"},
           @{"${package}::$special"} );
@@ -54,6 +46,42 @@
     $self->post_config();
 
     Apache::OK;
+}
+
+sub symdump
+{
+    my ($self) = @_;
+    return if $self->{_symdump}++;
+
+    my $pack = $self->package;
+
+    if (!$self->{symbols})
+    {
+        $self->{symbols} ||= [];
+
+        no strict;
+
+        #XXX: Shamelessly borrowed from Devel::Symdump;
+        while (my ($key, $val) = each(%{*{"$pack\::"}}))
+        {
+            local (*ENTRY) = $val;
+            if (defined $val && defined *ENTRY{SCALAR})
+            {
+                push @{$self->{symbols}}, [$key, $ENTRY];
+            }
+            if (defined $val && defined *ENTRY{ARRAY})
+            {
+                push @{$self->{symbols}}, [$key, \@ENTRY];
+            }
+            if (defined $val && defined *ENTRY{HASH} && $key !~ /::/)
+            {
+                push @{$self->{symbols}}, [$key, \%ENTRY];
+            }
+        }
+    }
+
+    return @{$self->{symbols}};
+
 }
 
 sub dump_special {

Re: [Patch] Default Handler and a wee bit more

Posted by Doug MacEachern <do...@covalent.net>.
excellent work Philippe!!  thanks, i've applied your patch.
one change i made was to remove the dependency on Devel::Symdump by simply 
making a copy of it into ModPerl::Symdump.  would happily apply patches 
that prune away the things we don't need there for Apache::PerlSection, 
such as inh_tree, etc.

sorry for the delay in getting it in.



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org