Hi.

I was reading RFC 271 and thinking about this pre/post handler thing. Why
instead of having 2 subs, one for pre and other for post condition, and
having to deal with things as strange as $_[-1], why don't we have only one
handler that calls the real sub?

Instead of:

 :  pre abc  {  do_pre_handler(@_);  }
 :  post abc {  do_post_handler($_[-1]); }

why not make it:

 :  pre_post_handler abc {
 :     do_pre_handler(@_);     # pre part
 :     my $result = REAL_SUB::abc(@_);
 :     do_post_handler($result);
 :     return $result;
 :  }

(Of course, the names "pre_post_handler" and "REAL_SUB" are completely
inadequate, what I'm trying to express is the idea here!)


Advantages of this method:
* Better nesting of pre and post handlers. If the sub throws an exception,
even so the handler could catch it, execute its clean-up code and then
re-throw it. (this is not addressed in the RFC).
* Possibility to execute the post handler even if the sub itself wasn't
executed.
* Easier to uninstall pre and post handlers. (I don't know if uninstalling
handlers is an issue, I believe it is. Using two separate subs leaves space
for uninstalling the pre-handler and forgetting to uninstall the
post-handler, or vice-versa, what might lead to unexpected behaviour.)
* No messing with $_[-1]. (Yeah, I really didn't like it !!!) The splice
behaviour also wasn't very clear to me. I believe the samples that use it to
change @_ assume the number of elements of @_ must be the same (???).

Disadvantages:
* The REAL_SUB:: stuff doesn't allow having anonymous subs as pre/post
handlers. I think an improvement would be passing the real sub as the first
parameter to the handler:

 :   sub abc_handler {
 :      my $real_abc = shift;
 :      do_pre_handler(@_);     # pre part
 :      my $result = $real_abc->(@_);
 :      do_post_handler($result);
 :      return $result;
 :   }
 :   push_handler(\&abc, \&abc_handler);

Or having the real sub reference in an implicit variable (such as $_). I,
personally, stick with the first one, but I list it down here for
completion:

 :   sub abc_handler {
 :      do_pre_handler(@_);     # pre part
 :      my $result = $_->(@_);
 :      do_post_handler($result);
 :      return $result;
 :   }
 :   push_handler(\&abc, \&abc_handler);



Well, what you think of it? Does it have disadvantages I'm not aware of?

Branden

Reply via email to