package Scope::CHECK; use 5.010; $VERSION = 0.001; use strict; { package Scope::CHECK::_OnScopeExit; sub new { bless $_[1], $_[0] } DESTROY { goto &{$_[0]} } } sub add { state @queue; state $Id = 0; shift; my ($code) = @_; push @queue, $code; $^H{__PACKAGE__ . '::_' . $Id++} = Scope::CHECK::_OnScopeExit::->new(sub { (pop @queue)->() }); } 1; __END__ =head1 NAME Scope::CHECK - Add CHECK blocks to the currently compiling lexical scope =head1 SYNOPSIS use 5.010; use strict; use Scope::CHECK; { BEGIN { say '1. Compiling block.' } BEGIN { Scope::CHECK::->add(sub { say '4. Checking block, again.' }); } BEGIN { Scope::CHECK::->add(sub { say '3. Checking block.' }); } BEGIN { say '2. Done compiling block.' } } BEGIN { say '5. Compiling rest of file.' } say '6. Running file.'; __END__ 1. Compiling block. 2. Done compiling block. 3. Checking block. 4. Checking block, again. 5. Compiling rest of file. 6. Running file. =head1 DESCRIPTION C lets you add C blocks to the currently compiling lexical scope. You probably want to do this because you need to defer code until the whole scope is done compiling. C blocks run in LIFO order, just as C and C blocks. C blocks at "unit scope", i.e. the same lexical scope as C lives in, currently execute before C blocks. This depends on the inner working of perl, and this order isn't defined anywhere as far as I know. =head1 METHODS =over =item Scope::CHECK->add(CODE) C takes a subroutine reference as the only argument. The subroutine will be executed when the currently compiling lexical scope is compiled. =back =head1 BUGS =over =item Not really C blocks As the blocks aren't really C blocks but only pretend to be, they might be executed too early before all compile passes are done. I don't know before/during/after which compile pass they're executed. If you don't use C blocks to manipulate the optree you're probably safe. Let me know if you have any problems related to this. =item Threads C may not work in combination with threads. As long as you don't B any threads while a C block is waiting to execute or inside a C block you probably won't have any problem. Here's an example of what can happen when you start a thread before an active C block has been executed: use 5.010; use strict; use Scope::CHECK; use threads; { BEGIN { Scope::CHECK::->add(sub { say 'CHECK' }) } BEGIN { threads::->create(sub { say 'Thread started and ended.' })->join } BEGIN { say 'Block compiled.' } } BEGIN { say 'Continuing compiling.' } __END__ Thread started and ended. CHECK Block compiled. CHECK Continuing compiling. Notice the extra CHECK in the output. The first is because the thread ended, and the block was thus run prematurely. If you find any way to detect that a block executed because a thread ended, please let me know. =item When no scope is compiling If no scope is being compiled the block will be executed when the program exits, after C blocks. This is not by design but due to current implementation. =back =head1 AUTHOR lodin =head1 COPYRIGHT Copyright 2008 lodin. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO L for C and C. =cut