NAME Sub::Block - manipulate blocks of code to assemble them into subs SYNOPSIS use Sub::Block; my $plus_one = block { $_[0] + 1 }; print $plus_one->(7); # 8 STATUS This is all pretty experimental at the moment. Consider it to be a proof-of-concept. DESCRIPTION Sub::Block allows you to create objects that are conceptually code blocks that can be composed with other code blocks to create subs which, when called, will run the code in the blocks without all of the overhead associated with a normal sub call. Another way to think about it is that it's a cleaner way of building closures than stringy eval. Assume for example that you have a coderef $is_even which checks whether a sub number is even, and you want to use "grep" to find all the even numbers in a list: my $is_even = sub { $_[0] % 2 == 0 }; my @even_nums = grep { $is_even->($_) } @list; If @list is 10,000 items long, the $is_even sub is called 10,000 times. Sub calls are relatively expensive in terms of CPU time, so it would be good if we could inline the contents of $is_even into the "grep" block, and thus avoid those 10,000 sub calls. With Sub::Block this is possible! my $is_even = block { $_[0] % 2 == 0 }; my $grep_even = eval sprintf( 'sub { grep { %s } @_ }', $is_even->inlininfy('$_'), ); # Below this comment, only a single sub call happens! my @even_nums = $grep_even->(@list); Constructors "new($coderef)" Creates a Sub::Block from an existing coderef. "new($string, \%captures)" Creates a Sub::Block from a string of Perl code, plus a hashref of variables to capture. "block { BLOCK }" This is not a method, but an exported function that acts as a shortcut for the constructor. Methods "sub" Returns the code block as a normal coderef. "&{}" is overloaded so that "$block->(@args)" works. "execute(@args)" Executes the code block, with @args. "closures" Returns the variables closed over by the code block. Note that Sub::Block is powered by Sub::Quote, and closures don't really work properly. See . "code" Returns a string of Perl code for the code block. "inlinify(@varnames)" Returns a string of Perl code for the code block, wrapped in a "do{...}" block with @_ localized and the variables in @varnames assigned to it. The following: my $plus_one = block { $_[0] + 1 }; print $plus_one->inlinify('$foo'); Will print something like: do { local @_ = ($foo); $_[0] + 1 }; "grep" A shortcut for the example earlier in this documentation: my $is_even = block { $_[0] % 2 == 0 }; my $grep_even = $is_even->grep; my @even_nums = $grep_even->execute(@list); But $grep_even is a Sub::Block, not a normal coderef "map" Like "grep", but "map". :-) "sequence(@others)" Given a list of other blocks (or coderefs, which will be converted into code blocks) generates a new block which calls all of the blocks in sequence, with the output of each being passed into the input of the next. my $block1 = block { ... }; my $block2 = block { ... }; my $block3 = block { ... }; # The following two are conceptually similar. my $seq1 = $block1->sequence($block2, $block3); my $seq2 = block { $block3->execute( $block2->execute( $block1->execute(@_) ) ); }; You can also use the overloaded ">>" operator: my $seq3 = $block1 >> $block2 >> $block3; Or it can be called as a class method: my $seq4 = Sub::Block->pipe($block1, $block2, $block3); CAVEATS Sub::Block is affected by . The "return", "wantarray" and "caller" functions which rely on the sub call stack will not see your code block when it's been inlined into an outer sub. So "return" will really return from the outer sub, not the code block. Sub::Block will issue a warning if it notices that you've used one of these keywords in your code block, but it might not always notice. (It needs to walk the optree to look for them.) BUGS Please report any bugs to . SEE ALSO Sub::Quote. AUTHOR Toby Inkster . COPYRIGHT AND LICENCE This software is copyright (c) 2013 by Toby Inkster. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. DISCLAIMER OF WARRANTIES THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.