hi all...
I just got around to fixing something that has been a splinter in my mind
for a while now...
it all started with Andrew Ford documenting that push_handlers() didn't
work for method handlers. it turns out they work just fine so long as you
use the (undocumented?) string literal form
$r->push_handlers(PerlInitHandler => 'My::Class->handler');
instead of the code reference form. While this makes sense, it bugged me.
anyway, I set to work on it this morning and was able to get method handlers
to work for the code reference form as well, but it required a patch to
UNIVERSAL::can().
the below patches allow the following formats, in addition to what is
already currently supported
$r->push_handlers(PerlFixupHandler => My::Class->can('foo'));
$r->set_handlers(PerlFixupHandler => [My::Class->can('foo')]);
at any rate, while the results may not be the best (or cleanest) approach,
it is an interesting proof-of-concept and was fun (well, sort of).
--Geoff
Index: mod_perl.c
===================================================================
RCS file: /home/cvspublic/modperl/src/modules/perl/mod_perl.c,v
retrieving revision 1.141
diff -u -r1.141 mod_perl.c
--- mod_perl.c 2001/07/10 03:30:27 1.141
+++ mod_perl.c 2001/08/15 17:01:23
@@ -1211,6 +1211,28 @@
MP_TRACE_h(fprintf(stderr, "checking if `%s' is a method...%s\n",
sub, (is_method ? "yes" : "no")));
SvREFCNT_dec(sv);
+
+ return is_method;
+}
+
+int perl_sv_ismethod(SV *sv)
+{
+ CV *cv;
+ HV *stash;
+ GV *gv;
+ int is_method=0;
+
+ cv = sv_2cv(sv, &stash, &gv, FALSE);
+
+#ifdef CVf_METHOD
+ if (cv && (CvFLAGS(cv) & CVf_METHOD)) {
+ is_method = 1;
+ }
+#endif
+
+ MP_TRACE_h(fprintf(stderr, "checking if CV is a method...%s\n",
+ (is_method ? "yes" : "no")));
+
return is_method;
}
#endif
@@ -1598,6 +1620,8 @@
#ifdef PERL_METHOD_HANDLERS
if(is_method)
XPUSHs(sv_2mortal(pclass));
+ else if (perl_sv_ismethod(sv))
+ XPUSHs(sv_2mortal(sv));
else
SvREFCNT_dec(pclass);
#else
--- universal.c Mon Jun 18 20:22:59 2001
+++ ~universal.c Wed Aug 15 13:42:56 2001
@@ -219,8 +219,10 @@
if (pkg) {
GV *gv = gv_fetchmethod_autoload(pkg, name, FALSE);
- if (gv && isGV(gv))
+ if (gv && isGV(gv)) {
+ CvMETHOD_on(GvCV(gv));
rv = sv_2mortal(newRV((SV*)GvCV(gv)));
+ }
}
ST(0) = rv;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]