Stevan Little


B::CompilerPhase::Hook - Programatically install BEGIN/CHECK/INIT/UNITCHECK/END blocks


version 0.02


  use B::CompilerPhase::Hook qw[

  # We call these functions within BEGIN
  # blocks so that we can be assured they
  # will enqueue properly, see the docs
  # for more info.

  print                         "10. Ordinary code runs at runtime.\n";
      enqueue_END       { print "16. So this is the end of the tale.\n" };
      enqueue_INIT      { print " 7. INIT blocks run FIFO just before runtime.\n" };
      enqueue_UNITCHECK { print " 4. And therefore before any CHECK blocks.\n" };
      enqueue_CHECK     { print " 6. So this is the sixth line.\n" }
  print                         "11. It runs in order, of course.\n";
      enqueue_BEGIN     { print " 1. BEGIN blocks run FIFO during compilation.\n" }
      enqueue_END       { print "15. Read perlmod for the rest of the story.\n" }
      enqueue_CHECK     { print " 5. CHECK blocks run LIFO after all compilation.\n" }
      enqueue_INIT      { print " 8. Run this again, using Perl's -c switch.\n" }
  print                         "12. This is anti-obfuscated code.\n";
      enqueue_END       { print "14. END blocks run LIFO at quitting time.\n" }
      enqueue_BEGIN     { print " 2. So this line comes out second.\n" }
      enqueue_UNITCHECK { print " 3. UNITCHECK blocks run LIFO after each file is compiled.\n" }
      enqueue_INIT      { print " 9. You'll see the difference right away.\n" }
  print                         "13.   It only _looks_ like it should be confusing.\n";

  # With apologies to the `BEGIN-UNITCHECK-CHECK-INIT-and-END` section of `perlmod`


This module makes it possible to enqueue callbacks to be run during the various Perl compiler phases, with the aim of doing multi-phase meta programming in a reasonably clean way.


These functions either push or unshift onto the respective internal arrays for that phase. The distinction is there to preserve the FIFO and LIFO patterns already inherent in the built-in form of compiler phase hooks.

All of these functions have the & prototype, as such can be called in block form if desired.

enqueue_BEGIN( $cb )

This will push the $cb onto the end of the internal BEGIN array.

enqueue_CHECK( $cb )

This will unshift the $cb onto the end of the internal CHECK array.

enqueue_INIT( $cb )

This will push the $cb onto the end of the internal INIT array.

enqueue_UNITCHECK( $cb )

This will unshift the $cb onto the end of the internal UNITCHECK array.

enqueue_END( $cb )

This will unshift the $cb onto the end of the internal END array.


For each of the phases we have a prepend_${phase} function, which will push and an append_${phase} function which will unshift.

These should be used with caution and only if you really understand what you are doing. For most cases you can just use the enqueue variants above and all will be well.



This module provides push and unshift access to the internal arrays that hold the set of compiler phase callbacks. It relies on you to do the right thing when choosing which of the two actions (push or unshift) to take.


Stevan Little <>


This software is copyright (c) 2017 by Stevan Little.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.