View on
MetaCPAN
Ben Morrow > B-Hooks-AtRuntime-1 > B::Hooks::AtRuntime

Download:
B-Hooks-AtRuntime-1.tar.gz

Dependencies

Annotate this POD

View/Report Bugs
Module Version: 1   Source   Latest Release: B-Hooks-AtRuntime-4

NAME ^

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

SYNOPSIS ^

    # My::Module
    sub import {
        at_runtime { warn "TWO" };
    }

    # elsewhere
    warn "ONE";
    use My::Module;
    warn "THREE";

DESCRIPTION ^

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.

Object lifetimes

at_runtime is careful to make sure the anonymous sub passed to it doesn't live any longer than it has to. It, 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.

B::Hooks::AtRuntime::run

If you look at a stack trace from within an at_runtime block, you will see there is a frame for a sub called B::Hooks::AtRuntime::run between your anonymous sub and the point where it was inserted. This is not a function you can call yourself (it is set up and destroyed as part of the lowering-to-runtime mechanism), but if for instance you wanted to use something like Scope::Upper to manipulate the runtime scope you need to be aware it will be there.

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.

CAVEATS ^

Perls before 5.12

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.

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.

SEE ALSO ^

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::Upper is useful for escaping (in a limited fashion) from at_runtime up to the scope it was inserted into.

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

AUTHOR ^

Ben Morrow <ben@morrow.me.uk>

BUGS ^

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

ACKNOWLEDGEMENTS ^

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

COPYRIGHT ^

Copyright 2012 Ben Morrow.

Released under the 2-clause BSD licence.

syntax highlighting: