line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Sub::Quote; |
2
|
|
|
|
|
|
|
|
3
|
5
|
|
|
5
|
|
63
|
sub _clean_eval { eval $_[0] } |
|
5
|
|
|
40
|
|
15
|
|
|
5
|
|
|
1
|
|
177
|
|
|
40
|
|
|
1
|
|
5015
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
1
|
|
|
|
4
|
|
|
|
|
|
|
|
5
|
11
|
|
|
11
|
|
578745
|
use strict; |
|
10
|
|
|
|
|
75
|
|
|
10
|
|
|
|
|
400
|
|
6
|
11
|
|
|
11
|
|
53
|
use warnings; |
|
11
|
|
|
|
|
20
|
|
|
11
|
|
|
|
|
320
|
|
7
|
|
|
|
|
|
|
|
8
|
11
|
|
|
11
|
|
14498
|
use Sub::Defer qw(defer_sub); |
|
10
|
|
|
|
|
22
|
|
|
10
|
|
|
|
|
449
|
|
9
|
11
|
|
|
11
|
|
61
|
use Scalar::Util qw(weaken); |
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
396
|
|
10
|
11
|
|
|
11
|
|
52
|
use Exporter qw(import); |
|
11
|
|
|
|
|
20
|
|
|
11
|
|
|
|
|
378
|
|
11
|
11
|
|
|
11
|
|
74
|
use Carp qw(croak); |
|
12
|
|
|
|
|
28
|
|
|
12
|
|
|
|
|
444
|
|
12
|
11
|
|
|
11
|
|
216
|
BEGIN { our @CARP_NOT = qw(Sub::Defer) } |
13
|
11
|
|
|
11
|
|
83
|
use B (); |
|
12
|
|
|
|
|
61
|
|
|
12
|
|
|
|
|
2456
|
|
14
|
|
|
|
|
|
|
BEGIN { |
15
|
11
|
100
|
|
11
|
|
325
|
*_HAVE_IS_UTF8 = defined &utf8::is_utf8 ? sub(){1} : sub(){0}; |
16
|
11
|
100
|
|
|
|
78
|
*_HAVE_PERLSTRING = defined &B::perlstring ? sub(){1} : sub(){0}; |
17
|
11
|
50
|
66
|
|
|
135
|
*_BAD_BACKSLASH_ESCAPE = _HAVE_PERLSTRING() && "$]" == 5.010_000 ? sub(){1} : sub(){0}; |
18
|
11
|
100
|
66
|
|
|
514
|
*_HAVE_HEX_FLOAT = !$ENV{SUB_QUOTE_NO_HEX_FLOAT} && "$]" >= 5.022 ? sub(){1} : sub(){0}; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# This may not be perfect, as we can't tell the format purely from the size |
21
|
|
|
|
|
|
|
# but it should cover the common cases, and other formats are more likely to |
22
|
|
|
|
|
|
|
# be less precise. |
23
|
11
|
|
|
|
|
120
|
my $nvsize = 8 * length pack 'F', 0; |
24
|
10
|
0
|
|
|
|
38
|
my $nvmantbits |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
25
|
|
|
|
|
|
|
= $nvsize == 16 ? 11 |
26
|
|
|
|
|
|
|
: $nvsize == 32 ? 24 |
27
|
|
|
|
|
|
|
: $nvsize == 64 ? 53 |
28
|
|
|
|
|
|
|
: $nvsize == 80 ? 64 |
29
|
|
|
|
|
|
|
: $nvsize == 128 ? 113 |
30
|
|
|
|
|
|
|
: $nvsize == 256 ? 237 |
31
|
|
|
|
|
|
|
: 237 # unknown float format |
32
|
|
|
|
|
|
|
; |
33
|
10
|
|
|
|
|
74
|
my $precision = int( log(2)/log(10)*$nvmantbits ); |
34
|
|
|
|
|
|
|
|
35
|
9
|
|
|
|
|
126
|
*_NVSIZE = sub(){$nvsize}; |
|
1
|
|
|
|
|
6
|
|
36
|
9
|
|
|
|
|
36
|
*_NVMANTBITS = sub(){$nvmantbits}; |
|
1
|
|
|
|
|
76
|
|
37
|
9
|
|
|
|
|
1744
|
*_FLOAT_PRECISION = sub(){$precision}; |
|
1
|
|
|
|
|
3
|
|
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
our $VERSION = '2.006006'; |
41
|
|
|
|
|
|
|
$VERSION =~ tr/_//d; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
our @EXPORT = qw(quote_sub unquote_sub quoted_from_sub qsub); |
44
|
|
|
|
|
|
|
our @EXPORT_OK = qw(quotify capture_unroll inlinify sanitize_identifier); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
our %QUOTED; |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
my %escape; |
49
|
|
|
|
|
|
|
if (_BAD_BACKSLASH_ESCAPE) { |
50
|
|
|
|
|
|
|
%escape = ( |
51
|
|
|
|
|
|
|
(map +(chr($_) => sprintf '\x%02x', $_), 0 .. 0x31, 0x7f), |
52
|
|
|
|
|
|
|
"\t" => "\\t", |
53
|
|
|
|
|
|
|
"\n" => "\\n", |
54
|
|
|
|
|
|
|
"\r" => "\\r", |
55
|
|
|
|
|
|
|
"\f" => "\\f", |
56
|
|
|
|
|
|
|
"\b" => "\\b", |
57
|
|
|
|
|
|
|
"\a" => "\\a", |
58
|
|
|
|
|
|
|
"\e" => "\\e", |
59
|
|
|
|
|
|
|
(map +($_ => "\\$_"), qw(" \ $ @)), |
60
|
|
|
|
|
|
|
); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub quotify { |
64
|
2366
|
|
|
2366
|
1
|
4414705
|
my $value = $_[0]; |
65
|
9
|
|
|
11
|
|
89
|
no warnings 'numeric'; |
|
9
|
|
|
|
|
19
|
|
|
9
|
|
|
|
|
19054
|
|
66
|
|
|
|
|
|
|
! defined $value ? 'undef()' |
67
|
|
|
|
|
|
|
# numeric detection |
68
|
|
|
|
|
|
|
: (!(_HAVE_IS_UTF8 && utf8::is_utf8($value)) |
69
|
|
|
|
|
|
|
&& length( (my $dummy = '') & $value ) |
70
|
|
|
|
|
|
|
&& 0 + $value eq $value |
71
|
|
|
|
|
|
|
) ? ( |
72
|
|
|
|
|
|
|
$value != $value ? ( |
73
|
|
|
|
|
|
|
$value eq (9**9**9*0) |
74
|
|
|
|
|
|
|
? '(9**9**9*0)' # nan |
75
|
|
|
|
|
|
|
: '(-(9**9**9*0))' # -nan |
76
|
|
|
|
|
|
|
) |
77
|
|
|
|
|
|
|
: $value == 9**9**9 ? '(9**9**9)' # inf |
78
|
|
|
|
|
|
|
: $value == -9**9**9 ? '(-9**9**9)' # -inf |
79
|
|
|
|
|
|
|
: $value == 0 ? ( |
80
|
|
|
|
|
|
|
sprintf('%g', $value) eq '-0' ? '-0.0' : '0', |
81
|
|
|
|
|
|
|
) |
82
|
|
|
|
|
|
|
: $value !~ /[e.]/i ? ( |
83
|
|
|
|
|
|
|
$value > 0 ? (sprintf '%u', $value) |
84
|
|
|
|
|
|
|
: (sprintf '%d', $value) |
85
|
|
|
|
|
|
|
) |
86
|
|
|
|
|
|
|
: do { |
87
|
164
|
|
|
|
|
366
|
my $float = $value; |
88
|
164
|
|
|
|
|
565
|
my $max_factor = int( log( abs($value) ) / log(2) ) - _NVMANTBITS; |
89
|
164
|
100
|
|
|
|
310
|
my $ex_sign = $max_factor > 0 ? 1 : -1; |
90
|
164
|
|
|
|
|
406
|
FACTOR: for my $ex (0 .. abs($max_factor)) { |
91
|
172
|
|
|
|
|
350
|
my $num = $value / 2**($ex_sign * $ex); |
92
|
172
|
|
|
|
|
245
|
for my $precision (_FLOAT_PRECISION .. _FLOAT_PRECISION+2) { |
93
|
317
|
|
|
|
|
1239
|
my $formatted = sprintf '%.'.$precision.'g', $num; |
94
|
317
|
100
|
|
|
|
593
|
$float = $formatted |
95
|
|
|
|
|
|
|
if $ex == 0; |
96
|
317
|
100
|
|
|
|
809
|
if ($formatted == $num) { |
97
|
158
|
100
|
|
|
|
360
|
if ($ex) { |
98
|
5
|
50
|
|
|
|
26
|
$float |
|
|
50
|
|
|
|
|
|
99
|
|
|
|
|
|
|
= $formatted |
100
|
|
|
|
|
|
|
. ($ex_sign == 1 ? '*' : '/') |
101
|
|
|
|
|
|
|
. ( |
102
|
|
|
|
|
|
|
$ex > _NVMANTBITS |
103
|
|
|
|
|
|
|
? "2**$ex" |
104
|
|
|
|
|
|
|
: sprintf('%u', 2**$ex) |
105
|
|
|
|
|
|
|
); |
106
|
|
|
|
|
|
|
} |
107
|
158
|
|
|
|
|
356
|
last FACTOR; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
} |
110
|
19
|
|
|
|
|
167
|
if (_HAVE_HEX_FLOAT) { |
111
|
65
|
|
|
|
|
189
|
$float = sprintf '%a', $value; |
112
|
11
|
|
|
|
|
32
|
last FACTOR; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
} |
115
|
112
|
|
|
|
|
366
|
"$float"; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
) |
118
|
|
|
|
|
|
|
: !length($value) && length( (my $dummy2 = '') & $value ) ? '(!1)' # false |
119
|
2366
|
100
|
100
|
|
|
25656
|
: _BAD_BACKSLASH_ESCAPE && _HAVE_IS_UTF8 && utf8::is_utf8($value) ? do { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
120
|
|
|
|
|
|
|
$value =~ s/(["\$\@\\[:cntrl:]]|[^\x00-\x7f])/ |
121
|
|
|
|
|
|
|
$escape{$1} || sprintf('\x{%x}', ord($1)) |
122
|
|
|
|
|
|
|
/ge; |
123
|
|
|
|
|
|
|
qq["$value"]; |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
: _HAVE_PERLSTRING ? B::perlstring($value) |
126
|
|
|
|
|
|
|
: qq["\Q$value\E"]; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
sub sanitize_identifier { |
130
|
3
|
|
|
3
|
1
|
477
|
my $name = shift; |
131
|
3
|
|
|
|
|
12
|
$name =~ s/([_\W])/sprintf('_%x', ord($1))/ge; |
|
6
|
|
|
|
|
44
|
|
132
|
2
|
|
|
|
|
35
|
$name; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub capture_unroll { |
136
|
43
|
|
|
44
|
1
|
1635
|
my ($from, $captures, $indent) = @_; |
137
|
|
|
|
|
|
|
join( |
138
|
|
|
|
|
|
|
'', |
139
|
|
|
|
|
|
|
map { |
140
|
43
|
100
|
|
|
|
104
|
/^([\@\%\$])/ |
|
89
|
|
|
|
|
601
|
|
141
|
|
|
|
|
|
|
or croak "capture key should start with \@, \% or \$: $_"; |
142
|
87
|
|
|
|
|
293
|
(' ' x $indent).qq{my ${_} = ${1}{${from}->{${\quotify $_}}};\n}; |
|
87
|
|
|
|
|
136
|
|
143
|
|
|
|
|
|
|
} keys %$captures |
144
|
|
|
|
|
|
|
); |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
sub inlinify { |
148
|
9
|
|
|
10
|
1
|
8805
|
my ($code, $args, $extra, $local) = @_; |
149
|
9
|
100
|
|
|
|
74
|
$args = '()' |
150
|
|
|
|
|
|
|
if !defined $args; |
151
|
9
|
|
100
|
|
|
29
|
my $do = 'do { '.($extra||''); |
152
|
9
|
100
|
|
|
|
36
|
if ($code =~ s/^(\s*package\s+([a-zA-Z0-9:]+);)//) { |
153
|
2
|
|
|
|
|
77
|
$do .= $1; |
154
|
|
|
|
|
|
|
} |
155
|
9
|
100
|
100
|
|
|
47
|
if ($code =~ s{ |
|
|
100
|
|
|
|
|
|
156
|
|
|
|
|
|
|
\A((?:\#\ BEGIN\ quote_sub\ PRELUDE\n.*?\#\ END\ quote_sub\ PRELUDE\n)?\s*) |
157
|
|
|
|
|
|
|
(^\s*) my \s* \(([^)]+)\) \s* = \s* \@_; |
158
|
|
|
|
|
|
|
}{}xms) { |
159
|
4
|
|
|
|
|
13
|
my ($pre, $indent, $code_args) = ($1, $2, $3); |
160
|
4
|
|
|
|
|
48
|
$do .= $pre; |
161
|
4
|
100
|
|
|
|
14
|
if ($code_args ne $args) { |
162
|
2
|
|
|
|
|
6
|
$do .= $indent . 'my ('.$code_args.') = ('.$args.'); '; |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
elsif ($local || $args ne '@_') { |
166
|
4
|
100
|
|
|
|
93
|
$do .= ($local ? 'local ' : '').'@_ = ('.$args.'); '; |
167
|
|
|
|
|
|
|
} |
168
|
9
|
|
|
|
|
40
|
$do.$code.' }'; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub quote_sub { |
172
|
|
|
|
|
|
|
# HOLY DWIMMERY, BATMAN! |
173
|
|
|
|
|
|
|
# $name => $code => \%captures => \%options |
174
|
|
|
|
|
|
|
# $name => $code => \%captures |
175
|
|
|
|
|
|
|
# $name => $code |
176
|
|
|
|
|
|
|
# $code => \%captures => \%options |
177
|
|
|
|
|
|
|
# $code |
178
|
60
|
100
|
100
|
61
|
1
|
22940
|
my $options = |
179
|
|
|
|
|
|
|
(ref($_[-1]) eq 'HASH' and ref($_[-2]) eq 'HASH') |
180
|
|
|
|
|
|
|
? pop |
181
|
|
|
|
|
|
|
: {}; |
182
|
60
|
100
|
|
|
|
187
|
my $captures = ref($_[-1]) eq 'HASH' ? pop : undef; |
183
|
60
|
100
|
100
|
|
|
181
|
undef($captures) if $captures && !keys %$captures; |
184
|
60
|
|
|
|
|
80
|
my $code = pop; |
185
|
60
|
|
|
|
|
115
|
my $name = $_[0]; |
186
|
60
|
100
|
|
|
|
103
|
if ($name) { |
187
|
22
|
|
|
|
|
26
|
my $subname = $name; |
188
|
22
|
100
|
|
|
|
177
|
my $package = $subname =~ s/(.*)::// ? $1 : caller; |
189
|
22
|
|
|
|
|
60
|
$name = join '::', $package, $subname; |
190
|
22
|
100
|
|
|
|
337
|
croak qq{package name "$package" too long!} |
191
|
|
|
|
|
|
|
if length $package > 252; |
192
|
20
|
100
|
|
|
|
294
|
croak qq{package name "$package" is not valid!} |
193
|
|
|
|
|
|
|
unless $package =~ /^[^\d\W]\w*(?:::\w+)*$/; |
194
|
18
|
100
|
|
|
|
116
|
croak qq{sub name "$subname" too long!} |
195
|
|
|
|
|
|
|
if length $subname > 252; |
196
|
17
|
100
|
|
|
|
196
|
croak qq{sub name "$subname" is not valid!} |
197
|
|
|
|
|
|
|
unless $subname =~ /^[^\d\W]\w*$/; |
198
|
|
|
|
|
|
|
} |
199
|
53
|
|
|
|
|
579
|
my @caller = caller(0); |
200
|
53
|
|
|
|
|
909
|
my ($attributes, $file, $line) = @{$options}{qw(attributes file line)}; |
|
53
|
|
|
|
|
107
|
|
201
|
52
|
100
|
|
|
|
96
|
if ($attributes) { |
202
|
|
|
|
|
|
|
/\A\w+(?:\(.*\))?\z/s || croak "invalid attribute $_" |
203
|
3
|
|
66
|
|
|
141
|
for @$attributes; |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
my $quoted_info = { |
206
|
|
|
|
|
|
|
name => $name, |
207
|
|
|
|
|
|
|
code => $code, |
208
|
|
|
|
|
|
|
captures => $captures, |
209
|
|
|
|
|
|
|
package => (exists $options->{package} ? $options->{package} : $caller[0]), |
210
|
|
|
|
|
|
|
hints => (exists $options->{hints} ? $options->{hints} : $caller[8]), |
211
|
|
|
|
|
|
|
warning_bits => (exists $options->{warning_bits} ? $options->{warning_bits} : $caller[9]), |
212
|
51
|
100
|
|
|
|
347
|
hintshash => (exists $options->{hintshash} ? $options->{hintshash} : $caller[10]), |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
213
|
|
|
|
|
|
|
($attributes ? (attributes => $attributes) : ()), |
214
|
|
|
|
|
|
|
($file ? (file => $file) : ()), |
215
|
|
|
|
|
|
|
($line ? (line => $line) : ()), |
216
|
|
|
|
|
|
|
}; |
217
|
51
|
|
|
|
|
58
|
my $unquoted; |
218
|
51
|
|
|
|
|
192
|
weaken($quoted_info->{unquoted} = \$unquoted); |
219
|
51
|
100
|
|
|
|
89
|
if ($options->{no_defer}) { |
220
|
4
|
|
|
|
|
5
|
my $fake = \my $var; |
221
|
4
|
|
|
|
|
10
|
local $QUOTED{$fake} = $quoted_info; |
222
|
4
|
|
|
|
|
8
|
my $sub = unquote_sub($fake); |
223
|
4
|
100
|
100
|
|
|
18
|
Sub::Defer::_install_coderef($name, $sub) if $name && !$options->{no_install}; |
224
|
4
|
|
|
|
|
17
|
return $sub; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
else { |
227
|
|
|
|
|
|
|
my $deferred = defer_sub( |
228
|
|
|
|
|
|
|
($options->{no_install} ? undef : $name), |
229
|
|
|
|
|
|
|
sub { |
230
|
30
|
|
|
32
|
|
33
|
$unquoted if 0; |
231
|
30
|
|
|
|
|
52
|
unquote_sub($quoted_info->{deferred}); |
232
|
|
|
|
|
|
|
}, |
233
|
|
|
|
|
|
|
{ |
234
|
|
|
|
|
|
|
($attributes ? ( attributes => $attributes ) : ()), |
235
|
47
|
100
|
|
|
|
268
|
($name ? () : ( package => $quoted_info->{package} )), |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
236
|
|
|
|
|
|
|
}, |
237
|
|
|
|
|
|
|
); |
238
|
47
|
|
|
|
|
129
|
weaken($quoted_info->{deferred} = $deferred); |
239
|
47
|
|
|
|
|
123
|
weaken($QUOTED{$deferred} = $quoted_info); |
240
|
47
|
|
|
|
|
181
|
return $deferred; |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub _context { |
245
|
47
|
|
|
49
|
|
78
|
my $info = shift; |
246
|
47
|
|
66
|
|
|
108
|
$info->{context} ||= do { |
247
|
|
|
|
|
|
|
my ($package, $hints, $warning_bits, $hintshash, $file, $line) |
248
|
41
|
|
|
|
|
51
|
= @{$info}{qw(package hints warning_bits hintshash file line)}; |
|
41
|
|
|
|
|
146
|
|
249
|
|
|
|
|
|
|
|
250
|
41
|
100
|
50
|
|
|
74
|
$line ||= 1 |
251
|
|
|
|
|
|
|
if $file; |
252
|
|
|
|
|
|
|
|
253
|
41
|
|
|
|
|
59
|
my $line_mark = ''; |
254
|
41
|
100
|
|
|
|
68
|
if ($line) { |
255
|
2
|
|
|
|
|
5
|
$line_mark = "#line ".($line-1); |
256
|
2
|
100
|
|
|
|
5
|
if ($file) { |
257
|
1
|
|
|
|
|
2
|
$line_mark .= qq{ "$file"}; |
258
|
|
|
|
|
|
|
} |
259
|
2
|
|
|
|
|
2
|
$line_mark .= "\n"; |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
$info->{context} |
263
|
|
|
|
|
|
|
="# BEGIN quote_sub PRELUDE\n" |
264
|
|
|
|
|
|
|
."package $package;\n" |
265
|
|
|
|
|
|
|
."BEGIN {\n" |
266
|
|
|
|
|
|
|
." \$^H = ".quotify($hints).";\n" |
267
|
|
|
|
|
|
|
." \${^WARNING_BITS} = ".quotify($warning_bits).";\n" |
268
|
|
|
|
|
|
|
." \%^H = (\n" |
269
|
|
|
|
|
|
|
. join('', map |
270
|
|
|
|
|
|
|
" ".quotify($_)." => ".quotify($hintshash->{$_}).",\n", |
271
|
41
|
|
33
|
|
|
113
|
grep !(ref $hintshash->{$_} && $hintshash->{$_} =~ /\A(?:\w+(?:::\w+)*=)?[A-Z]+\(0x[[0-9a-fA-F]+\)\z/), |
272
|
|
|
|
|
|
|
keys %$hintshash) |
273
|
|
|
|
|
|
|
." );\n" |
274
|
|
|
|
|
|
|
."}\n" |
275
|
|
|
|
|
|
|
.$line_mark |
276
|
|
|
|
|
|
|
."# END quote_sub PRELUDE\n"; |
277
|
|
|
|
|
|
|
}; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub quoted_from_sub { |
281
|
10
|
|
|
15
|
1
|
379
|
my ($sub) = @_; |
282
|
10
|
100
|
50
|
|
|
40
|
my $quoted_info = $QUOTED{$sub||''} or return undef; |
283
|
|
|
|
|
|
|
my ($name, $code, $captures, $unquoted, $deferred) |
284
|
8
|
|
|
|
|
15
|
= @{$quoted_info}{qw(name code captures unquoted deferred)}; |
|
8
|
|
|
|
|
20
|
|
285
|
8
|
|
|
|
|
17
|
$code = _context($quoted_info) . $code; |
286
|
8
|
|
66
|
|
|
51
|
$unquoted &&= $$unquoted; |
287
|
8
|
100
|
100
|
|
|
44
|
if (($deferred && $deferred eq $sub) |
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
288
|
|
|
|
|
|
|
|| ($unquoted && $unquoted eq $sub)) { |
289
|
7
|
|
|
|
|
35
|
return [ $name, $code, $captures, $unquoted, $deferred ]; |
290
|
|
|
|
|
|
|
} |
291
|
1
|
|
|
|
|
2
|
return undef; |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub unquote_sub { |
295
|
43
|
|
|
45
|
1
|
568
|
my ($sub) = @_; |
296
|
43
|
100
|
|
|
|
104
|
my $quoted_info = $QUOTED{$sub} or return undef; |
297
|
42
|
|
|
|
|
59
|
my $unquoted = $quoted_info->{unquoted}; |
298
|
42
|
100
|
66
|
|
|
118
|
unless ($unquoted && $$unquoted) { |
299
|
|
|
|
|
|
|
my ($name, $code, $captures, $package, $attributes) |
300
|
40
|
|
|
|
|
54
|
= @{$quoted_info}{qw(name code captures package attributes)}; |
|
40
|
|
|
|
|
95
|
|
301
|
|
|
|
|
|
|
|
302
|
40
|
100
|
|
|
|
115
|
($package, $name) = $name =~ /(.*)::(.*)/ |
303
|
|
|
|
|
|
|
if $name; |
304
|
|
|
|
|
|
|
|
305
|
40
|
100
|
|
|
|
79
|
my %captures = $captures ? %$captures : (); |
306
|
40
|
|
|
|
|
62
|
$captures{'$_UNQUOTED'} = \$unquoted; |
307
|
40
|
|
|
|
|
55
|
$captures{'$_QUOTED'} = \$quoted_info; |
308
|
|
|
|
|
|
|
|
309
|
40
|
100
|
|
|
|
76
|
my $make_sub |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
310
|
|
|
|
|
|
|
= "{\n" |
311
|
|
|
|
|
|
|
. capture_unroll("\$_[1]", \%captures, 2) |
312
|
|
|
|
|
|
|
. " package ${package};\n" |
313
|
|
|
|
|
|
|
. ( |
314
|
|
|
|
|
|
|
$name |
315
|
|
|
|
|
|
|
# disable the 'variable $x will not stay shared' warning since |
316
|
|
|
|
|
|
|
# we're not letting it escape from this scope anyway so there's |
317
|
|
|
|
|
|
|
# nothing trying to share it |
318
|
|
|
|
|
|
|
? " no warnings 'closure';\n sub ${name} " |
319
|
|
|
|
|
|
|
: " \$\$_UNQUOTED = sub " |
320
|
|
|
|
|
|
|
) |
321
|
|
|
|
|
|
|
. ($attributes ? join('', map ":$_ ", @$attributes) : '') . "{\n" |
322
|
|
|
|
|
|
|
. " (\$_QUOTED,\$_UNQUOTED) if 0;\n" |
323
|
|
|
|
|
|
|
. _context($quoted_info) |
324
|
|
|
|
|
|
|
. $code |
325
|
|
|
|
|
|
|
. " }".($name ? "\n \$\$_UNQUOTED = \\&${name}" : '') . ";\n" |
326
|
|
|
|
|
|
|
. "}\n" |
327
|
|
|
|
|
|
|
. "1;\n"; |
328
|
39
|
100
|
|
|
|
119
|
if (my $debug = $ENV{SUB_QUOTE_DEBUG}) { |
329
|
12
|
100
|
|
|
|
62
|
if ($debug =~ m{^([^\W\d]\w*(?:::\w+)*(?:::)?)$}) { |
|
|
100
|
|
|
|
|
|
330
|
9
|
|
|
|
|
18
|
my $filter = $1; |
331
|
9
|
100
|
50
|
|
|
36
|
my $match |
|
|
100
|
100
|
|
|
|
|
332
|
|
|
|
|
|
|
= $filter =~ /::$/ ? $package.'::' |
333
|
|
|
|
|
|
|
: $filter =~ /::/ ? $package.'::'.($name||'__ANON__') |
334
|
|
|
|
|
|
|
: ($name||'__ANON__'); |
335
|
9
|
100
|
|
|
|
42
|
warn $make_sub |
336
|
|
|
|
|
|
|
if $match eq $filter; |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
elsif ($debug =~ m{\A/(.*)/\z}s) { |
339
|
2
|
|
|
|
|
5
|
my $filter = $1; |
340
|
2
|
100
|
|
|
|
20
|
warn $make_sub |
341
|
|
|
|
|
|
|
if $code =~ $filter; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
else { |
344
|
1
|
|
|
|
|
8
|
warn $make_sub; |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
{ |
348
|
9
|
|
|
11
|
|
126
|
no strict 'refs'; |
|
9
|
|
|
|
|
13
|
|
|
9
|
|
|
|
|
2416
|
|
|
39
|
|
|
|
|
74
|
|
349
|
39
|
100
|
|
|
|
110
|
local *{"${package}::${name}"} if $name; |
|
13
|
|
|
|
|
50
|
|
350
|
39
|
|
|
|
|
50
|
my ($success, $e); |
351
|
|
|
|
|
|
|
{ |
352
|
39
|
|
|
|
|
40
|
local $@; |
|
39
|
|
|
|
|
73
|
|
353
|
39
|
|
|
|
|
81
|
$success = _clean_eval($make_sub, \%captures); |
354
|
39
|
|
|
|
|
134
|
$e = $@; |
355
|
|
|
|
|
|
|
} |
356
|
39
|
100
|
|
|
|
89
|
unless ($success) { |
357
|
2
|
|
|
|
|
8
|
my $space = length($make_sub =~ tr/\n//); |
358
|
2
|
|
|
|
|
4
|
my $line = 0; |
359
|
2
|
|
|
|
|
8
|
$make_sub =~ s/^/sprintf "%${space}d: ", ++$line/emg; |
|
39
|
|
|
|
|
94
|
|
360
|
2
|
|
|
|
|
170
|
croak "Eval went very, very wrong:\n\n${make_sub}\n\n$e"; |
361
|
|
|
|
|
|
|
} |
362
|
37
|
|
|
|
|
202
|
weaken($QUOTED{$$unquoted} = $quoted_info); |
363
|
|
|
|
|
|
|
} |
364
|
|
|
|
|
|
|
} |
365
|
39
|
|
|
|
|
137
|
$$unquoted; |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
sub qsub ($) { |
369
|
1
|
|
|
2
|
1
|
512
|
goto "e_sub; |
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
sub CLONE { |
373
|
5
|
|
|
6
|
|
147
|
my @quoted = map { defined $_ ? ( |
374
|
2
|
|
|
|
|
5
|
$_->{unquoted} && ${$_->{unquoted}} ? (${ $_->{unquoted} } => $_) : (), |
375
|
8
|
100
|
100
|
|
|
23
|
$_->{deferred} ? ($_->{deferred} => $_) : (), |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
376
|
|
|
|
|
|
|
) : () } values %QUOTED; |
377
|
5
|
|
|
|
|
20
|
%QUOTED = @quoted; |
378
|
5
|
|
|
|
|
17
|
weaken($_) for values %QUOTED; |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
1; |
382
|
|
|
|
|
|
|
__END__ |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=encoding utf-8 |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
=head1 NAME |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
Sub::Quote - Efficient generation of subroutines via string eval |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=head1 SYNOPSIS |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
package Silly; |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
use Sub::Quote qw(quote_sub unquote_sub quoted_from_sub); |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
quote_sub 'Silly::kitty', q{ print "meow" }; |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
quote_sub 'Silly::doggy', q{ print "woof" }; |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
my $sound = 0; |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
quote_sub 'Silly::dagron', |
403
|
|
|
|
|
|
|
q{ print ++$sound % 2 ? 'burninate' : 'roar' }, |
404
|
|
|
|
|
|
|
{ '$sound' => \$sound }; |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
And elsewhere: |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
Silly->kitty; # meow |
409
|
|
|
|
|
|
|
Silly->doggy; # woof |
410
|
|
|
|
|
|
|
Silly->dagron; # burninate |
411
|
|
|
|
|
|
|
Silly->dagron; # roar |
412
|
|
|
|
|
|
|
Silly->dagron; # burninate |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
=head1 DESCRIPTION |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
This package provides performant ways to generate subroutines from strings. |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=head1 SUBROUTINES |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=head2 quote_sub |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
my $coderef = quote_sub 'Foo::bar', q{ print $x++ . "\n" }, { '$x' => \0 }; |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
Arguments: ?$name, $code, ?\%captures, ?\%options |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
C<$name> is the subroutine where the coderef will be installed. |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
C<$code> is a string that will be turned into code. |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
C<\%captures> is a hashref of variables that will be made available to the |
431
|
|
|
|
|
|
|
code. The keys should be the full name of the variable to be made available, |
432
|
|
|
|
|
|
|
including the sigil. The values should be references to the values. The |
433
|
|
|
|
|
|
|
variables will contain copies of the values. See the L</SYNOPSIS>'s |
434
|
|
|
|
|
|
|
C<Silly::dagron> for an example using captures. |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
Exported by default. |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=head3 options |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
=over 2 |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=item C<no_install> |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
B<Boolean>. Set this option to not install the generated coderef into the |
445
|
|
|
|
|
|
|
passed subroutine name on undefer. |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
=item C<no_defer> |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
B<Boolean>. Prevents a Sub::Defer wrapper from being generated for the quoted |
450
|
|
|
|
|
|
|
sub. If the sub will most likely be called at some point, setting this is a |
451
|
|
|
|
|
|
|
good idea. For a sub that will most likely be inlined, it is not recommended. |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
=item C<package> |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
The package that the quoted sub will be evaluated in. If not specified, the |
456
|
|
|
|
|
|
|
package from sub calling C<quote_sub> will be used. |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=item C<hints> |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
The value of L<< C<$^H> | perlvar/$^H >> to use for the code being evaluated. |
461
|
|
|
|
|
|
|
This captures the settings of the L<strict> pragma. If not specified, the value |
462
|
|
|
|
|
|
|
from the calling code will be used. |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=item C<warning_bits> |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
The value of L<< C<${^WARNING_BITS}> | perlvar/${^WARNING_BITS} >> to use for |
467
|
|
|
|
|
|
|
the code being evaluated. This captures the L<warnings> set. If not specified, |
468
|
|
|
|
|
|
|
the warnings from the calling code will be used. |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
=item C<%^H> |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
The value of L<< C<%^H> | perlvar/%^H >> to use for the code being evaluated. |
473
|
|
|
|
|
|
|
This captures additional pragma settings. If not specified, the value from the |
474
|
|
|
|
|
|
|
calling code will be used if possible (on perl 5.10+). |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=item C<attributes> |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
The L<perlsub/Subroutine Attributes> to apply to the sub generated. Should be |
479
|
|
|
|
|
|
|
specified as an array reference. The attributes will be applied to both the |
480
|
|
|
|
|
|
|
generated sub and the deferred wrapper, if one is used. |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
=item C<file> |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
The apparent filename to use for the code being evaluated. |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
=item C<line> |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
The apparent line number |
489
|
|
|
|
|
|
|
to use for the code being evaluated. |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=back |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=head2 unquote_sub |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
my $coderef = unquote_sub $sub; |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
Forcibly replace subroutine with actual code. |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
If $sub is not a quoted sub, this is a no-op. |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
Exported by default. |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=head2 quoted_from_sub |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
my $data = quoted_from_sub $sub; |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
my ($name, $code, $captures, $compiled_sub) = @$data; |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
Returns original arguments to quote_sub, plus the compiled version if this |
510
|
|
|
|
|
|
|
sub has already been unquoted. |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
Note that $sub can be either the original quoted version or the compiled |
513
|
|
|
|
|
|
|
version for convenience. |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
Exported by default. |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
=head2 inlinify |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
my $prelude = capture_unroll '$captures', { |
520
|
|
|
|
|
|
|
'$x' => 1, |
521
|
|
|
|
|
|
|
'$y' => 2, |
522
|
|
|
|
|
|
|
}, 4; |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
my $inlined_code = inlinify q{ |
525
|
|
|
|
|
|
|
my ($x, $y) = @_; |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
print $x + $y . "\n"; |
528
|
|
|
|
|
|
|
}, '$x, $y', $prelude; |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
Takes a string of code, a string of arguments, a string of code which acts as a |
531
|
|
|
|
|
|
|
"prelude", and a B<Boolean> representing whether or not to localize the |
532
|
|
|
|
|
|
|
arguments. |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
=head2 quotify |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
my $quoted_value = quotify $value; |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
Quotes a single (non-reference) scalar value for use in a code string. The |
539
|
|
|
|
|
|
|
result should reproduce the original value, including strings, undef, integers, |
540
|
|
|
|
|
|
|
and floating point numbers. The resulting floating point numbers (including |
541
|
|
|
|
|
|
|
infinites and not a number) should be precisely equal to the original, if |
542
|
|
|
|
|
|
|
possible. The exact format of the resulting number should not be relied on, as |
543
|
|
|
|
|
|
|
it may include hex floats or math expressions. |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
=head2 capture_unroll |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
my $prelude = capture_unroll '$captures', { |
548
|
|
|
|
|
|
|
'$x' => 1, |
549
|
|
|
|
|
|
|
'$y' => 2, |
550
|
|
|
|
|
|
|
}, 4; |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
Arguments: $from, \%captures, $indent |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
Generates a snippet of code which is suitable to be used as a prelude for |
555
|
|
|
|
|
|
|
L</inlinify>. C<$from> is a string will be used as a hashref in the resulting |
556
|
|
|
|
|
|
|
code. The keys of C<%captures> are the names of the variables and the values |
557
|
|
|
|
|
|
|
are ignored. C<$indent> is the number of spaces to indent the result by. |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
=head2 qsub |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
my $hash = { |
562
|
|
|
|
|
|
|
coderef => qsub q{ print "hello"; }, |
563
|
|
|
|
|
|
|
other => 5, |
564
|
|
|
|
|
|
|
}; |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
Arguments: $code |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
Works exactly like L</quote_sub>, but includes a prototype to only accept a |
569
|
|
|
|
|
|
|
single parameter. This makes it easier to include in hash structures or lists. |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
Exported by default. |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
=head2 sanitize_identifier |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
my $var_name = '$variable_for_' . sanitize_identifier('@name'); |
576
|
|
|
|
|
|
|
quote_sub qq{ print \$${var_name} }, { $var_name => \$value }; |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
Arguments: $identifier |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
Sanitizes a value so that it can be used in an identifier. |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
=head1 ENVIRONMENT |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
=head2 SUB_QUOTE_DEBUG |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
Causes code to be output to C<STDERR> before being evaled. Several forms are |
587
|
|
|
|
|
|
|
supported: |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
=over 4 |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
=item C<1> |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
All subs will be output. |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
=item C</foo/> |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
Subs will be output if their code matches the given regular expression. |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
=item C<simple_identifier> |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
Any sub with the given name will be output. |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=item C<Full::identifier> |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
A sub matching the full name will be output. |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
=item C<Package::Name::> |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
Any sub in the given package (including anonymous subs) will be output. |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
=back |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
=head1 CAVEATS |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
Much of this is just string-based code-generation, and as a result, a few |
616
|
|
|
|
|
|
|
caveats apply. |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
=head2 return |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
Calling C<return> from a quote_sub'ed sub will not likely do what you intend. |
621
|
|
|
|
|
|
|
Instead of returning from the code you defined in C<quote_sub>, it will return |
622
|
|
|
|
|
|
|
from the overall function it is composited into. |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
So when you pass in: |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
quote_sub q{ return 1 if $condition; $morecode } |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
It might turn up in the intended context as follows: |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
sub foo { |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
<important code a> |
633
|
|
|
|
|
|
|
do { |
634
|
|
|
|
|
|
|
return 1 if $condition; |
635
|
|
|
|
|
|
|
$morecode |
636
|
|
|
|
|
|
|
}; |
637
|
|
|
|
|
|
|
<important code b> |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
} |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
Which will obviously return from foo, when all you meant to do was return from |
642
|
|
|
|
|
|
|
the code context in quote_sub and proceed with running important code b. |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
=head2 pragmas |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
C<Sub::Quote> preserves the environment of the code creating the |
647
|
|
|
|
|
|
|
quoted subs. This includes the package, strict, warnings, and any |
648
|
|
|
|
|
|
|
other lexical pragmas. This is done by prefixing the code with a |
649
|
|
|
|
|
|
|
block that sets up a matching environment. When inlining C<Sub::Quote> |
650
|
|
|
|
|
|
|
subs, care should be taken that user pragmas won't effect the rest |
651
|
|
|
|
|
|
|
of the code. |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
=head1 SUPPORT |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
Users' IRC: #moose on irc.perl.org |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
=for :html |
658
|
|
|
|
|
|
|
L<(click for instant chatroom login)|http://chat.mibbit.com/#moose@irc.perl.org> |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
Development and contribution IRC: #web-simple on irc.perl.org |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
=for :html |
663
|
|
|
|
|
|
|
L<(click for instant chatroom login)|http://chat.mibbit.com/#web-simple@irc.perl.org> |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
Bugtracker: L<https://rt.cpan.org/Public/Dist/Display.html?Name=Sub-Quote> |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
Git repository: L<git://github.com/moose/Sub-Quote.git> |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
Git browser: L<https://github.com/moose/Sub-Quote> |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=head1 AUTHOR |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk> |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
=head1 CONTRIBUTORS |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
frew - Arthur Axel "fREW" Schmidt (cpan:FREW) <frioux@gmail.com> |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
ribasushi - Peter Rabbitson (cpan:RIBASUSHI) <ribasushi@cpan.org> |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com> |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
tobyink - Toby Inkster (cpan:TOBYINK) <tobyink@cpan.org> |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
haarg - Graham Knop (cpan:HAARG) <haarg@cpan.org> |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
bluefeet - Aran Deltac (cpan:BLUEFEET) <bluefeet@gmail.com> |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
ether - Karen Etheridge (cpan:ETHER) <ether@cpan.org> |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
dolmen - Olivier Mengué (cpan:DOLMEN) <dolmen@cpan.org> |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
alexbio - Alessandro Ghedini (cpan:ALEXBIO) <alexbio@cpan.org> |
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
getty - Torsten Raudssus (cpan:GETTY) <torsten@raudss.us> |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
arcanez - Justin Hunter (cpan:ARCANEZ) <justin.d.hunter@gmail.com> |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
kanashiro - Lucas Kanashiro (cpan:KANASHIRO) <kanashiro.duarte@gmail.com> |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
djerius - Diab Jerius (cpan:DJERIUS) <djerius@cfa.harvard.edu> |
702
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
=head1 COPYRIGHT |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
Copyright (c) 2010-2016 the Sub::Quote L</AUTHOR> and L</CONTRIBUTORS> |
706
|
|
|
|
|
|
|
as listed above. |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
=head1 LICENSE |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
This library is free software and may be distributed under the same terms |
711
|
|
|
|
|
|
|
as perl itself. See L<http://dev.perl.org/licenses/>. |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
=cut |