GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
B::Hooks::AtRuntime(3) User Contributed Perl Documentation B::Hooks::AtRuntime(3)

B::Hooks::AtRuntime - Lower blocks from compile time to runtime

    # My::Module
    sub import {
        at_runtime { warn "TWO" };
    }
    # elsewhere
    warn "ONE";
    use My::Module;
    warn "THREE";

This module allows code that runs at compile-time to do something at runtime. A block passed to "at_runtime" gets compiled into the code that's currently compiling, and will be called when control reaches that point at runtime. In the example in the SYNOPSIS, the warnings will occur in order, and if that section of code runs more than once, so will all three warnings.

    at_runtime { ... };

This sets up a block to be called at runtime. It must be called from within a "BEGIN" block or "use", otherwise there will be no compiling code to insert into. The innermost enclosing "BEGIN" block, which would normally be invisible once the section of code it is in has been compiled, will effectively leave behind a call to the given block. For example, this

    BEGIN { warn "ONE" }    warn "one";
    BEGIN { warn "TWO";     at_runtime { warn "two" }; }

will warn "ONE TWO one two", with the last warning 'lowered' out of the "BEGIN" block and back into the runtime control flow.

This applies even if calls to other subs intervene between "BEGIN" and "at_runtime". The lowered block is always inserted at the innermost point where perl is still compiling, so something like this

    # My::Module
    sub also_at_runtime { 
        my ($msg) = @_; 
        at_runtime { warn $msg };
    }
    sub import {
        my ($class, $one, $two) = @_;
        at_runtime { warn $one };
        also_at_runtime $two;
    }
    # 
    warn "one";
    BEGIN { at_runtime { warn "two" } }
    BEGIN { My::Module::also_at_runtime "three" }
    use My::Module "four", "five";

will still put the warnings in order.

    after_runtime { ... };

This arranges to call the block when runtime execution reaches the end of the surrounding compiling scope. For example, this will warn in order:

    warn "one";
    {
        warn "two";
        BEGIN { 
            after_runtime { warn "five" };
            at_runtime { warn "three" };
        }
        warn "four";
    }
    warn "six";

No exception handling is done, so if the block throws an exception it will propogate normally into the surrounding code. (This is different from the way perl calls "DESTROY" methods, which have their exceptions converted into warnings.)

Note that the block will be called during stack unwind, so the package, file and line information for "caller 0" will be the point where the surrounding scope was called. This is the same as a "DESTROY" method.

"at_runtime" and "after_runtime" are careful to make sure the anonymous sub passed to them doesn't live any longer than it has to. That sub, and any lexicals it has closed over, will be destroyed when the optree it has been compiled into is destroyed: for code outside any sub, this is when the containing file or eval finishes executing; for named subs, this is when the sub is un- or redefined; and for anonymous subs, this is not until both the code containing the "sub { }" expression and all instances generated by that expression have been destroyed.

    lex_stuff $text;

This is the function underlying "at_runtime". Under perl 5.12 and later, this is just a Perl wrapper for the core function lex_stuff_sv. Under earlier versions it is implemented with a source filter, with some limitations, see "CAVEATS" below.

This function pushes text into perl's line buffer, at the point perl is currently compiling. You should probably not try to push too much at once without giving perl a chance to compile it. If $text contains newlines, they will affect perl's idea of the current line number. You probably shouldn't use this function at all.

B::Hooks::AtRuntime uses Exporter::Tiny, so you can customise its exports as described by that module's documentation. "at_runtime" is exported by default; "after_runtime" and "lex_stuff" can be exported on request.

Version 1 used a different implementation for "at_runtime", which left an extra scope between the provided block and the code it was compiled into. Version 2 has removed this.

Versions of perl before 5.12.0 don't have the "lex_stuff_sv" function, and don't export enough for it to be possible to emulate it entirely. (B::Hooks::Parser gets as close as it can, and just exactly doesn't quite do what we need for "at_runtime".) This means our "lex_stuff" has to fall back to using a source filter to insert the text, which has a couple of important limitations.

  • You cannot stuff text into a string "eval".

    String evals aren't affected by source filters, so the stuffed text would end up getting inserted into the innermost compiling scope that wasn't a string eval. Since this would be rather confusing, and different from what 5.12 does, "lex_stuff" and "at_runtime" will croak if you try to use them to affect a string eval.

  • Stuffed text appears at the start of the next line.

    This, unfortunately, is rather annoying. With a filter, the earliest point at which we can insert text is the start of the next line. This means that if there is any text between the closing brace of the "BEGIN" block or the semicolon of the "use" that caused the insertion, and the end of the line, the insertion will certainly be in the wrong place and probably cause a syntax error.

    "lex_stuff" (and, therefore, "at_runtime") will issue a warning if this is going to happen (specifically, if there are any non-space non-comment characters between the point where we want to insert and the point we're forced to settle for), but this may not be something you can entirely control. If you are writing a module like the examples above which calls "at_runtime" from its "import" method, what matters is that users of your module not put anything on a line after your module's "use" statement.

If you want to use the filter implementation on perl 5.12 (for testing), set "PERL_B_HOOKS_ATRUNTIME=filter" in the environment. If the filter implementation is in use, "B::Hooks::AtRuntime::USE_FILTER" will be true.

B::Hooks::Parser will insert text 'here' in perls before 5.12, but requires a setup step at least one source line in advance.

Hook::AfterRuntime uses it to implement something somewhat similar to this module.

Scope::OnExit and B::Hooks::EndOfScope provide hooks into different points in the surrounding scope.

Filter::Util::Call is the generic interface to the source filtering mechanism.

Ben Morrow <ben@morrow.me.uk>

Please report any bugs to <bug-B-Hooks-AtRuntime@rt.cpan.org>.

Zefram's work on the core lexer API made this module enormously easier.

Copyright 2015 Ben Morrow.

Released under the 2-clause BSD licence.

2025-07-03 perl v5.40.2

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.