Thanks! I think that idea will work just fine, though I needed to think a
bit to avoid implementing it via cut-n-paste. I like the idea because
it should also, I think, cooperate with packages that don't take that
strategy. (Counter examples, welcome of course - but see how I've
implemented it first).
Since I have no control over when the global variable will be set, I
needed to do the copy of the original handler/installation of my handler
immediately before each call to third party module subroutines. At first
I thought that meant fairly repetitive hand-coding of wrapper subs for
each sub that needed a custom handler. That seems to me a bit of a hack.
Then it occurred to me that I can avoid the hand-coding simply by
require'ing rather than use'ing the package. Then,
instead of importing, I would play around with the symbol table a bit in
the begin block, like this:
- require the 3rd party module
- for each sub X that uses the global error handler, manufacture a
wrapper sub that
- saves the original handler
- manufactures a closure that calls a custom handler If the
custom handler didn't handle the exception, then the closure
would call the original handler
- sets the (localized) global handler to manufactured closure
- calls sub X
- assign the manufactured wrapper to a sub of the same name in the
package namespace
For those who might be interested in this approach (or in case tilly
has some ideas of an even better way to implement this), I've added a code
sample below, in three parts. The first part is a dummy 3rd party class with
a global variable as a handler. The second part is a sample extension module
implementing tilly interception suggestion using generated wrappers. And
the third part is a short demo showing that both the custom and global
handler indeed get called properly even when the global handler is redefined
long after all modules have been compiled and loaded.
Although this works, it isn't exactly a beginner Perl extension strategy.
The implementation requires an understanding of localization, symbol tables,
begin blocks, closures, and subroutine generators. Even as it solves my
problem with global handlers as a customization design, it underscores why
global variables as a customization strategy are not a good idea - unless, of course, I've missed an
easier way to do this.
An ideal customization design would be something that preserved documented behavior, allowed for stable code, was non-disruptive, involved minimal or no cut-n-paste and could be used safely by a programmer
with a basic knowledge of Perl.
All the same, this does solve my immediate problem, so
Many, many thanks for pointing the way, beth
| [reply] [d/l] [select] |