line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package POE::Component::Sequence::Nested; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=head1 NAME |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
POE::Component::Sequence::Nested - Adds special features to nested sequences |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 SYNOPSIS |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
use POE qw(Component::Sequence::Nested); |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
POE::Component::Sequence |
12
|
|
|
|
|
|
|
->new( |
13
|
|
|
|
|
|
|
{ |
14
|
|
|
|
|
|
|
auto_pause => 1, |
15
|
|
|
|
|
|
|
auto_resume => 1, |
16
|
|
|
|
|
|
|
merge_heap => 1, |
17
|
|
|
|
|
|
|
}, |
18
|
|
|
|
|
|
|
sub { |
19
|
|
|
|
|
|
|
POE::Component::Sequence |
20
|
|
|
|
|
|
|
->new( |
21
|
|
|
|
|
|
|
sub { |
22
|
|
|
|
|
|
|
my $subseq = shift; |
23
|
|
|
|
|
|
|
$subseq->heap_set( |
24
|
|
|
|
|
|
|
a => 5, |
25
|
|
|
|
|
|
|
b => 19, |
26
|
|
|
|
|
|
|
op => '+', |
27
|
|
|
|
|
|
|
); |
28
|
|
|
|
|
|
|
}, |
29
|
|
|
|
|
|
|
)->run; |
30
|
|
|
|
|
|
|
}, |
31
|
|
|
|
|
|
|
sub { |
32
|
|
|
|
|
|
|
my $sequence = shift; |
33
|
|
|
|
|
|
|
my $math = join ' ', map { $sequence->heap_index($_) } qw(a op b); |
34
|
|
|
|
|
|
|
$sequence->heap_set(result => eval $math); |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
) |
37
|
|
|
|
|
|
|
->add_callback(sub { |
38
|
|
|
|
|
|
|
my ($sequence, $result) = @_; |
39
|
|
|
|
|
|
|
print "Answer was " . $sequence->heap_index('result') . "\n"; |
40
|
|
|
|
|
|
|
}) |
41
|
|
|
|
|
|
|
->run(); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head1 DESCRIPTION |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
A nested sequence is one in which the return value of an action is another Sequence. When this is the case, we can perform some automated tasks which save each action from redundant calls. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
By itself it does nothing, but given any of the following actions, it will do it's magic: |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head2 auto_resume |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=over 4 |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
The parent sequence remains paused, but the child sequence has a callback added onto it which will resume the parent sequence: |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
$child_sequence->add_callback(sub { |
56
|
|
|
|
|
|
|
$parent_sequence->resume; |
57
|
|
|
|
|
|
|
}); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=back |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=head2 auto_error |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=over 4 |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
This propogates a child sequence failure to the parent via $child->add_error_callback(). This would happen anyway if the child sequence throws an exception, but if the child sequence is already catching errors via another callback |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=back |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=head2 merge_heap |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=over 4 |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
The heap of the child sequence will be merged with the parent when it's complete: |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
$child_sequence->add_finally_callback(sub { |
76
|
|
|
|
|
|
|
$parent_sequence->heap_set( $child_sequence->heap ); |
77
|
|
|
|
|
|
|
}); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
This allows for shared heap access. |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=back |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=cut |
84
|
|
|
|
|
|
|
|
85
|
1
|
|
|
1
|
|
866
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
48
|
|
86
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
37
|
|
87
|
1
|
|
|
1
|
|
7
|
use POE::Component::Sequence; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
88
|
1
|
|
|
1
|
|
6
|
use Scalar::Util qw(blessed); |
|
1
|
|
|
|
|
12
|
|
|
1
|
|
|
|
|
517
|
|
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
BEGIN { |
91
|
|
|
|
|
|
|
unshift @POE::Component::Sequence::_plugin_handlers, |
92
|
|
|
|
|
|
|
sub { |
93
|
12
|
|
|
|
|
16
|
my ($self, $request) = @_; |
94
|
|
|
|
|
|
|
|
95
|
12
|
|
|
|
|
25
|
my $action = $request->{action}; |
96
|
12
|
|
|
|
|
16
|
my $opt = $request->{options}; |
97
|
|
|
|
|
|
|
|
98
|
12
|
50
|
33
|
|
|
96
|
if (! defined $action || ! ref $action || ref $action ne 'CODE') { |
|
|
|
33
|
|
|
|
|
99
|
0
|
|
|
|
|
0
|
return { deferred => 1 }; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
12
|
|
|
|
|
44
|
my $return = $action->(@_); |
103
|
|
|
|
|
|
|
|
104
|
11
|
50
|
100
|
|
|
259
|
if ($return && ref $return && blessed $return |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
105
|
|
|
|
|
|
|
&& $return->isa('POE::Component::Sequence')) { |
106
|
6
|
100
|
|
|
|
19
|
if (delete $opt->{auto_resume}) { |
107
|
|
|
|
|
|
|
$return->add_finally_callback(sub { |
108
|
2
|
|
|
|
|
8
|
$self->resume; |
109
|
2
|
|
|
|
|
16
|
}); |
110
|
|
|
|
|
|
|
} |
111
|
6
|
100
|
|
|
|
18
|
if (delete $opt->{auto_error}) { |
112
|
|
|
|
|
|
|
$return->add_error_callback(sub { |
113
|
1
|
|
|
|
|
5
|
$self->failed($_[1]); |
114
|
1
|
|
|
|
|
9
|
}); |
115
|
|
|
|
|
|
|
} |
116
|
6
|
100
|
|
|
|
15
|
if (delete $opt->{merge_heap}) { |
117
|
|
|
|
|
|
|
$return->add_finally_callback(sub { |
118
|
1
|
|
|
|
|
31
|
my %transaction_heap = $_[1]->heap; |
119
|
1
|
|
|
|
|
42
|
$self->heap_set(%transaction_heap); |
120
|
1
|
|
|
|
|
7
|
}); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
11
|
|
|
|
|
53
|
return { value => $return }; |
125
|
1
|
|
|
1
|
|
31
|
}; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
1; |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
__END__ |