File Coverage

blib/lib/Future/AsyncAwait/Hooks.pm
Criterion Covered Total %
statement 19 20 95.0
branch 3 6 50.0
condition n/a
subroutine 5 5 100.0
pod 0 1 0.0
total 27 32 84.3


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2023 -- leonerd@leonerd.org.uk
5              
6             package Future::AsyncAwait::Hooks 0.01;
7              
8 2     2   240992 use v5.14;
  2         17  
9 2     2   11 use warnings;
  2         11  
  2         49  
10              
11 2     2   11 use Carp;
  2         4  
  2         536  
12              
13             require XSLoader;
14             XSLoader::load( __PACKAGE__, our $VERSION );
15              
16             =head1 NAME
17              
18             C - scoped hook blocks that run extra code around C expressions
19              
20             =head1 SYNOPSIS
21              
22             use Future::AsyncAwait;
23             use Future::AsyncAwait::Hooks;
24              
25             async sub do_work
26             {
27             suspend { say "do_work is pausing here" }
28             resume { say "do_Work has woken up again" }
29              
30             my $result = (await inner_1()) + (await inner_2());
31             return $result;
32             }
33              
34             =head1 DESCRIPTION
35              
36             This module provides two extra syntax keywords for inserting code that can
37             observe the suspend and resume behaviour of C expressions within an
38             C.
39              
40             These two keywords are lexically scoped. They affect C expressions
41             later within their own scope, or scopes nested within it. They do not affect
42             any C expressions in scopes outside of those in which they appear.
43              
44             =cut
45              
46             =head1 KEYWORDS
47              
48             =head2 suspend
49              
50             async sub {
51             suspend { BLOCK }
52             }
53              
54             Inserts a block of code to run every time a subsequent C expression
55             at this block level pauses execution of the C.
56              
57             =head2 resume
58              
59             async sub {
60             resume { BLOCK }
61             }
62              
63             Inserts a block of code to run every time a subsequent C expression
64             at this block level resumes execution of the C after a pause.
65              
66             =cut
67              
68             sub import
69             {
70 1     1   6 my $class = shift;
71 1         3 my $caller = caller;
72              
73 1         6 $class->import_into( $caller, @_ );
74             }
75              
76             sub import_into
77             {
78 1     1 0 2 my $class = shift;
79 1         2 my ( $caller, @syms ) = @_;
80              
81 1 50       5 @syms or @syms = qw( suspend resume );
82              
83 1         3 my %syms = map { $_ => 1 } @syms;
  2         7  
84              
85 1         4 foreach (qw( suspend resume )) {
86 2 50       18 $^H{"Future::AsyncAwait::Hooks/$_"}++ if delete $syms{$_};
87             }
88              
89 1 50       2758 croak "Unrecognised import symbols @{[ keys %syms ]}" if keys %syms;
  0            
90             }
91              
92             =head1 TODO
93              
94             =over 4
95              
96             =item *
97              
98             Implement blocks as true blocks, rather than anon subs wrapped in CVs. This
99             will be slightly nontrivial as it has implications on how the optree fragment
100             gets executed, and what it still sees of the pad while it runs.
101              
102             =item *
103              
104             Maybe work out why it doesn't appear to work on perls older than 5.24. Or
105             maybe nobody will be writing new code and needs it back that old?
106              
107             =back
108              
109             =cut
110              
111             =head1 AUTHOR
112              
113             Paul Evans
114              
115             =cut
116              
117             0x55AA;