>>>>> "PRL" == Perl6 RFC Librarian <[EMAIL PROTECTED]> writes:
PRL> If a handler changes one of the original arguments through the
PRL> aliases in its @_ array, those changes a passed on to subsequent
PRL> handlers and to the primary itself. For example:
PRL> pre tax_payable_on {
PRL> $_[0] -= 20.00; # routinely underquote sales price
PRL> }
PRL> sub tax_payable_on { # now sees prices $20 less than
PRL> # specified argument
PRL> printf("Tax: %.2lf", $_[0] * 0.1);
PRL> }
PRL> tax_payable_on(99.95); # prints 8.00
PRL> tax_payable_on(29.95); # prints 0.99
PRL> tax_payable_on( 9.95); # prints -1.01 (a profit!)
i assume like normal subs, that changes the original argument in the
caller. what about splicing new values in/out of @_? is that allowed? i
can see passing in things which get deleted/expanded if they are in a
different format than the primary expects.
PRL> post tax_payable_on {
PRL> $_[-1] -= 1.00; # routinely underquote tax payable
PRL> }
the IRS will get you for that!
PRL> Either a block or subroutine reference implementing the handler,
PRL> or a hash reference whose value is a sub reference implementing
PRL> the handler, or a string or bareword specifying the logical name
PRL> of a handler. This argument would be optional.
the 'hash ref whose value' makes no sense. do you mean the keys are the
primary sub names and values are the pre/post sub refs for those
primaries?
PRL> If the first argument ends in "::" and is therefore the name of a
PRL> package -- rather than a subroutine -- then the handler is
PRL> installed in a special I<package prefix sequence>, and is shared
PRL> by every existing (and future) subroutine in the package. For
PRL> example:
PRL> pre Cafe::Bar::, sub { print "calling some method of
PRL> class Cafe::Bar" };
PRL> installs a prefix handler that will be invoked whenever I<any>
PRL> subroutine from package Cafe::Bar is called.
can you have a package level pre and also a per sub pre? do they
both get called or does the sub one only get called?
PRL> If the first argument is a subroutine reference, the handler is installed
PRL> for the referent. For example:
PRL> package Foo;
PRL> pre \&Zan::Zi::bar, sub { print "about to bar()..." };
PRL> installs a prefix handler for the subroutine C<&Zan::Zi::bar>, whilst:
PRL> package Foo;
PRL> my $anon = sub { print "I am the sub with no name\n" };
PRL> pre $anon, sub { print "about to bar()..." };
PRL> installs a prefix handler for the anonymous subroutine referred
PRL> to by $anon.
so the handlers are attached to the primary code ref? how does this work
with package level ones then? all subs must check for pakcage level pre
before they can be called? this sounds like a big slowdown. i am not
sure package level pre is a good idea in this case.
PRL> =head2 Installing C<post> Handlers
why the separate docs for post and pre syntax? without double checking,
i assume they have the same syntax other than pre/post. folding these
into one section would make this easier to digest.
PRL> =head2 Logically Identified Handlers
PRL> In order to later manipulate or remove prefix and postfix
PRL> handlers, it is convenient to given them a logical name. To this
PRL> end, the second argument to C<pre> or C<post> may be specified as
PRL> reference to a one-element hash:
PRL> pre Lum::bar, { PAIN => sub { print "ouch!..." } };
PRL> post Lum::bar, { PAIN => sub { print "...ahhh!" } };
this is getting a little ugly and too much IMO.
PRL> =head3 Accessing named handlers
PRL> Finally, it is possible to retrieve the entire prefix or postfix
PRL> handler sequence for a particular subroutine, by passing just its
PRL> name/reference to C<pre>:
PRL> $pain_handler_array_ref = pre Lum::bar;
PRL> $tree_handler_array_ref = post \&Coola::bar;
PRL> $package_handler_array_ref = pre Cafe::Bar::;
PRL> This returns a reference to the actual handler sequence for the
PRL> subroutine, in which each element is a reference to a hash whose single
PRL> key is the logical name of the handler (or "" if it has no logical name)
PRL> and whose single value is a reference to the handler itself. That is, the
PRL> structure of the returned value is like this:
PRL> [
PRL> { 'NAME' => sub {...} },
PRL> { 'NAME' => sub {...} },
PRL> { '' => sub {...} },
PRL> { 'NAME' => sub {...} },
PRL> { '' => sub {...} },
PRL> ]
why not just use a single list? the short anon hashes are useless
there. in fact, you could use this to eliminate the need for all the
named handlers. just make the pre/post functions take multiple code refs
as handlers. you can retrieve that list by calling pre/post with no code
ref. then you just manipulate that list on your own. much simpler to get
the same effects.
pre Foo, sub {}, sub {} ;
$Foo_handlers = pre Foo ;
$Foo_handlers is now [ \&, \& ]
it is amusing how most of us don't want SQL/DBMS stuff like NULL in perl
(myself included) but trigger like stuff like your handlers seems ok.
for one thing, this is not hard to describe in basic terms (until you
get to the inheritance stuff) and it is useful in many ways. maybe you
should rename this as triggers as handlers have a meaning is signals and
in event callbacks.
uri
--
Uri Guttman --------- [EMAIL PROTECTED] ---------- http://www.sysarch.com
SYStems ARCHitecture, Software Engineering, Perl, Internet, UNIX Consulting
The Perl Books Page ----------- http://www.sysarch.com/cgi-bin/perl_books
The Best Search Engine on the Net ---------- http://www.northernlight.com