| Devel-Hook documentation | view source | Contained in the Devel-Hook distribution. |
Devel::Hook - Mess around with BEGIN/CHECK/INIT/END blocks
use Devel::Hook ();
INIT {
print "INIT #2\n";
}
BEGIN {
Devel::Hook->push_INIT_hook( sub { print "INIT #3 (hook)\n" } );
Devel::Hook->unshift_INIT_hook( sub { print "INIT #1 (hook)\n" } );
}
print "RUNTIME\n";
Output will be:
INIT #1 (hook) INIT #2 INIT #3 (hook) RUNTIME
Perl keeps arrays of subroutines that are executed
at the beginning and at the end of a running Perl program
and its program units. These subroutines correspond
to the special code blocks: BEGIN, UNITCHECK,
CHECK, INIT and END.
(See details at BEGIN, UNITCHECK, CHECK, INIT and END in perlmod.)
This module provides
limited capabilities to manipulate these arrays.
Such arrays belong to Perl's internals that you're
not supposed to see. Entries in these arrays get
consumed by the interpreter as it enters distinct
compilation phases, triggered by statements like
require, use, do, eval, etc.
To play as safest as possible, the only allowed
operations are to add entries to the start and to
the end of these arrays.
# add code hooks to the start of <BLOCK> array Devel::Hook->unshift_<BLOCK>_hook( @blocks ); # add code hooks to the end of <BLOCK> array Devel::Hook->push_<BLOCK>_hook( @blocks );
where <BLOCK> is one of: BEGIN,
UNITCHECK, CHECK, INIT or END.
The hooks execute first if they are at the start of the array and last if they are at the end. Notice that the FIFO or LIFO nature of blocks according to their textual order of appearance at Perl source does not matter here. For example, BEGIN, UNITCHECK and INIT are FIFO (first-in, first-out) blocks while CHECK and END are LIFO (last-in, first-out). But the Perl interpreter and the user of this module inserts blocks at the start of arrays if they should execute earlier and at the end if they are to be executed later, with a homogeneous treatment with respect to the block arrays.
If you are curious about the content of these arrays, read more at WARNING in Manip::END and proceed to the innards of Perl (perlhack).
If you want to inject code into Perl compilation phases or at the end of the program, this module may be useful.
If it can be done with literal BEGIN/UNITCHECK/CHECK/INIT/END
blocks, it should be. For weirder things, maybe
Devel::Hook can solve it.
As an example of application, Devel::Sub::Trace uses this module
to insert a INIT hook which will run just before any
other runtime code in the caller's package, wrapping
subs after they were compiled/generated but before
they get called by runtime code.
(not yet finished)
With care. We are in the terrain of Perl internals we are not supposed to mess with. And furthermore, if you don't understand the implications of what you are doing with this module, it is likely not to do what you want.
(to be finished)
Devel::Hook->unshift_BEGIN_hook( @blocks ); Devel::Hook->push_BEGIN_hook( @blocks );
This will add the blocks to the start (unshift_BEGIN_hook)
and to the end (push_BEGIN_hook) of the array of BEGIN
hooks.
@blocks is an array of subroutine references.
Devel::Hook->unshift_UNITCHECK_hook( @blocks ); Devel::Hook->push_UNITCHECK_hook( @blocks );
This will add the blocks to the start (unshift_UNITCHECK_hook)
and to the end (push_UNITCHECK_hook) of the array of UNITCHECK
hooks.
@blocks is an array of subroutine references.
The first stable release with UNITCHECK was 5.10.0.
For earlier releases, these methods die.
Devel::Hook->unshift_CHECK_hook( @blocks ); Devel::Hook->push_CHECK_hook( @blocks );
This will add the blocks to the start (unshift_CHECK_hook)
and to the end (push_CHECK_hook) of the array of CHECK
hooks.
@blocks is an array of subroutine references.
Devel::Hook->unshift_INIT_hook( @blocks ); Devel::Hook->push_INIT_hook( @blocks );
This will add the blocks to the start (unshift_INIT_hook)
and to the end (push_INIT_hook) of the array of INIT
hooks.
@blocks is an array of subroutine references.
Devel::Hook->unshift_END_hook( @blocks ); Devel::Hook->push_END_hook( @blocks );
This will add the blocks to the start (unshift_END_hook)
and to the end (push_END_hook) of the array of END
hooks.
For END hooks, by adding to the start of the array (unshift), they will be the first code blocks executed by Perl when it is exiting.
For END hooks, by adding to the end of the array (push), they will be the last code blocks executed by Perl when it is exiting.
@blocks is an array of subroutine references.
BEGIN, UNITCHECK, CHECK, INIT and END in perlmod
Please report bugs via CPAN RT http://rt.cpan.org/NoAuth/Bugs.html?Dist=Devel-Hook or mailto://bugs-Devel-Hook@rt.cpan.org
Devel::Hooks::BLOCK Everything I needed to learn about XS to write this module was borrowed from Manip::END written by Fergal Daly. To be really honest, the code was all there and I pruned it to a safer/limited/smaller API and included the manipulation to other hooks besides END blocks. And I also plagiarized his documentation.
Fergal Daly (for the code in Manip::END)
Adriano R. Ferreira, <ferreira@cpan.org>
Copyright (C) 2008 by Adriano R. Ferreira
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Devel-Hook documentation | view source | Contained in the Devel-Hook distribution. |