line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package here::declare;
|
2
|
2
|
|
|
2
|
|
51603
|
use warnings;
|
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
78
|
|
3
|
2
|
|
|
2
|
|
10
|
use strict;
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
74
|
|
4
|
2
|
|
|
2
|
|
1996
|
use lib '..';
|
|
2
|
|
|
|
|
1787
|
|
|
2
|
|
|
|
|
12
|
|
5
|
2
|
|
|
2
|
|
1468
|
use here::install;
|
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
13
|
|
6
|
2
|
|
|
2
|
|
2673
|
BEGIN {*croak = *here::croak}
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our ($name, $value, $glob);
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
sub process_pairs {
|
11
|
4
|
|
|
4
|
0
|
13
|
my %args = @_;
|
12
|
4
|
|
50
|
|
|
25
|
exists $args{$_} or croak "needs $_" for qw(validate transform);
|
13
|
|
|
|
|
|
|
sub (&@) {
|
14
|
10
|
|
33
|
10
|
|
46
|
my $to_source = $args{to_source} || shift;
|
|
|
|
|
10
|
|
|
|
15
|
|
|
|
|
|
|
my $run = sub {
|
16
|
15
|
100
|
|
15
|
|
41
|
if (@_ == 1) {
|
17
|
2
|
50
|
|
|
|
17
|
(local $value = $_[0])
|
18
|
|
|
|
|
|
|
=~ s/^ \s* (\(? [^)=]+ \)?) \s* = \s* (?=\S)//x
|
19
|
|
|
|
|
|
|
or croak 'argument must look like: ... = ...';
|
20
|
2
|
|
|
|
|
3
|
local $name = $1;
|
21
|
2
|
|
|
|
|
4
|
local $glob = my $error = 'here::declare::error::flag';
|
22
|
2
|
50
|
|
|
|
4
|
(my $perl = $to_source->())
|
23
|
|
|
|
|
|
|
=~ /$error/ and croak 'not supported with the single argument syntax';
|
24
|
2
|
|
|
|
|
8
|
return $perl
|
25
|
|
|
|
|
|
|
}
|
26
|
13
|
100
|
|
|
|
54
|
if ($_[0] =~ /^\s* \( ([^)=]+) \) \s*$/x) {
|
27
|
2
|
|
|
|
|
5
|
my $names = $1;
|
28
|
2
|
50
|
|
|
|
12
|
my $re = $names =~ /,/ ? qr/,/ : qr/\s+/;
|
29
|
2
|
|
|
|
|
10
|
splice @_, 0, 1, [grep {s/^\s+|\s+$//; 1} split $re => $names]
|
|
6
|
|
|
|
|
16
|
|
|
6
|
|
|
|
|
15
|
|
30
|
|
|
|
|
|
|
}
|
31
|
13
|
100
|
66
|
|
|
60
|
if (ref $_[0] eq 'ARRAY' and @_ > 2 || ref $_[1] ne 'ARRAY') {
|
|
|
|
66
|
|
|
|
|
32
|
3
|
|
|
|
|
13
|
@_ = ($_[0], [@_[1 .. $#_]])
|
33
|
|
|
|
|
|
|
}
|
34
|
13
|
100
|
100
|
|
|
71
|
if (@_ == 2 and ref $_[0] eq 'ARRAY'
|
|
|
|
66
|
|
|
|
|
35
|
|
|
|
|
|
|
and ref $_[1] eq 'ARRAY') {
|
36
|
22
|
|
|
|
|
68
|
@_ = map {
|
37
|
6
|
|
|
|
|
13
|
$_[0][$_] => $_[1][$_]
|
38
|
6
|
|
|
|
|
9
|
} 0 .. $#{$_[0]}
|
39
|
|
|
|
|
|
|
}
|
40
|
13
|
50
|
|
|
|
37
|
@_ % 2 and croak 'even length list expected';
|
41
|
34
|
|
|
|
|
143
|
map {
|
42
|
13
|
|
|
|
|
62
|
(local $name = $_[$_]) =~ s/^-?(\w)/\$$1/;
|
43
|
34
|
|
|
|
|
161
|
local ($value, $glob) = ($_[$_+1], substr $name, 1);
|
44
|
34
|
|
|
|
|
74
|
$args{validate}->();
|
45
|
34
|
|
|
|
|
65
|
$value = $args{transform}->();
|
46
|
34
|
|
|
|
|
549
|
$to_source->()
|
47
|
|
|
|
|
|
|
} map 2*$_ => 0 .. $#_/2
|
48
|
10
|
|
|
|
|
45
|
};
|
49
|
10
|
50
|
|
|
|
50
|
@_ ? &$run : $run
|
50
|
|
|
|
|
|
|
}
|
51
|
4
|
|
|
|
|
1050
|
}
|
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
BEGIN {
|
54
|
|
|
|
|
|
|
my %valid = (
|
55
|
23
|
|
|
|
|
59
|
'$' => sub {},
|
56
|
3
|
50
|
|
|
|
11
|
'@' => sub {ref $value eq 'ARRAY' ? () : "an ARRAY ref"},
|
57
|
3
|
50
|
|
|
|
11
|
'%' => sub {ref $value eq 'HASH' ? () : "a HASH ref"},
|
58
|
2
|
|
|
2
|
|
28
|
);
|
59
|
|
|
|
|
|
|
*lexical = process_pairs
|
60
|
|
|
|
|
|
|
validate => sub {
|
61
|
29
|
|
|
|
|
54
|
$name =~ /^(.)/;
|
62
|
|
|
|
|
|
|
croak "$name must be set with $_"
|
63
|
29
|
|
33
|
|
|
94
|
for ($valid{$1} or croak "type not supported: $name")->()
|
64
|
|
|
|
|
|
|
},
|
65
|
|
|
|
|
|
|
transform => sub {
|
66
|
29
|
|
|
|
|
65
|
my $code = here::store($value);
|
67
|
29
|
100
|
|
|
|
104
|
$name =~ /^([\@\%])/ ? $1."{$code}" : $code
|
68
|
2
|
|
|
|
|
20
|
};
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
*const = process_pairs
|
71
|
|
|
|
|
|
|
validate => sub {
|
72
|
5
|
50
|
|
|
|
22
|
$name =~ /^\$/ or croak "const sets scalar variables";
|
73
|
5
|
50
|
|
|
|
125
|
ref $value and croak "const values can be numbers or strings, not references";
|
74
|
|
|
|
|
|
|
},
|
75
|
|
|
|
|
|
|
transform => sub {
|
76
|
5
|
|
|
|
|
1963
|
require Data::Dumper;
|
77
|
5
|
|
|
|
|
15094
|
Data::Dumper->new([$value])->Terse(1)->Indent(0)->Dump
|
78
|
2
|
|
|
|
|
11
|
};
|
79
|
|
|
|
|
|
|
}
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
my %can = (
|
82
|
|
|
|
|
|
|
const => const {"our $name; BEGIN {*$glob = \\$value}"},
|
83
|
|
|
|
|
|
|
const2 => const {"sub $glob () {$value} our $name; BEGIN {*$glob = \\$glob}"},
|
84
|
|
|
|
|
|
|
);
|
85
|
|
|
|
|
|
|
for my $type (qw(my our state)) {
|
86
|
|
|
|
|
|
|
$can{$type} = lexical {"$type $name; BEGIN {$name = $value}"}
|
87
|
|
|
|
|
|
|
}
|
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
my %done;
|
90
|
|
|
|
|
|
|
sub import {
|
91
|
3
|
|
|
3
|
|
4133
|
shift;
|
92
|
3
|
50
|
|
|
|
22
|
for (@_ ? @_ : keys %can) {
|
93
|
15
|
50
|
|
|
|
46
|
$can{lc $_} or map {croak "pragma keys: $_; subroutine keys: \U$_"}
|
|
0
|
|
|
|
|
0
|
|
94
|
|
|
|
|
|
|
join ', ' => sort keys %can;
|
95
|
15
|
50
|
|
|
|
40
|
if (/[A-Z]/) {
|
96
|
2
|
|
|
2
|
|
21
|
no strict 'refs';
|
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
614
|
|
97
|
0
|
|
|
|
|
0
|
*{(caller).'::'.$_} = $can{lc $_};
|
|
0
|
|
|
|
|
0
|
|
98
|
|
|
|
|
|
|
}
|
99
|
|
|
|
|
|
|
else {
|
100
|
15
|
50
|
|
|
|
45
|
$done{$_}++ and next;
|
101
|
15
|
|
|
|
|
48
|
here::install::->import($_ => $can{$_})
|
102
|
|
|
|
|
|
|
}
|
103
|
|
|
|
|
|
|
}
|
104
|
|
|
|
|
|
|
}
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
sub unimport {
|
107
|
1
|
|
|
1
|
|
7
|
shift;
|
108
|
1
|
50
|
|
|
|
7
|
for (@_ ? @_ : keys %done) {
|
109
|
5
|
|
|
|
|
7
|
delete $done{$_};
|
110
|
5
|
|
|
|
|
14
|
here::install::->unimport($_)
|
111
|
|
|
|
|
|
|
}
|
112
|
|
|
|
|
|
|
}
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
our $VERSION = '0.03';
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=head1 NAME
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
here::declare - easily declare compile time variables
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=head1 VERSION
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
version 0.03
|
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
use here::declare;
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
use const qw($ONE 1 $TWO 2);
|
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
use my [qw(x y z)] => [$ONE + $TWO, 4, 5];
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
use our '@foo' => [$x, $y, $z];
|
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
is equivalent to:
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
our ($ONE, $TWO);
|
138
|
|
|
|
|
|
|
BEGIN {
|
139
|
|
|
|
|
|
|
*ONE = \'1';
|
140
|
|
|
|
|
|
|
*TWO = \'2';
|
141
|
|
|
|
|
|
|
}
|
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
my ($x, $y, $z);
|
144
|
|
|
|
|
|
|
BEGIN {
|
145
|
|
|
|
|
|
|
($x, $y, $z) = ($ONE + $TWO, 4, 5);
|
146
|
|
|
|
|
|
|
}
|
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
our @foo;
|
149
|
|
|
|
|
|
|
BEGIN {
|
150
|
|
|
|
|
|
|
@foo = ($x, $y, $z);
|
151
|
|
|
|
|
|
|
}
|
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
without all that tedious typing.
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=head1 USE STATEMENTS
|
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
all aspects of C< here::declare > must normally be imported using C< use ...; >
|
158
|
|
|
|
|
|
|
statements.
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
without arguments, an initial C< use here::declare; > line creates all five
|
161
|
|
|
|
|
|
|
pseudo-modules (C< my our state const const2 >). if you only want some, pass a
|
162
|
|
|
|
|
|
|
list of those.
|
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
in the following examples, the C< use my > declaration will be used. its usage
|
165
|
|
|
|
|
|
|
is equivalent to C< use our > and C< use state >.
|
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=head2 a single argument with C< = >
|
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=over 4
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
use my '$x = 1';
|
172
|
|
|
|
|
|
|
use my '($y, $z) = (2, 3)';
|
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
this is the simplest transform, which given an argument matching C< foo = bar >
|
175
|
|
|
|
|
|
|
gets rewritten as:
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
my foo; BEGIN {foo = bar}
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
so the above becomes:
|
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
my $x; BEGIN {$x = 1}
|
182
|
|
|
|
|
|
|
my ($y, $z); BEGIN {($y, $z) = (2, 3)}
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
while this version looks the closest to perl's native variable declarations, it
|
185
|
|
|
|
|
|
|
is unable to pass arguments that can not easily be written in a string.
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=back
|
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=head2 list of name/value pairs
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=over 4
|
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
use my '$say' => sub {print @_, $/};
|
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
use my '@array' => [1, 2, 3], '%hash' => {a => 1, b => 2};
|
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
here an arbitrarily long list of name/value pairs is passed to the declarator.
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
if the name is a C< $scalar > then the corresponding value will be copied into
|
200
|
|
|
|
|
|
|
the newly created variable at compile time. it is safe to pass any type of
|
201
|
|
|
|
|
|
|
scalar as a value, and it will not be stringified. C< bareword > and
|
202
|
|
|
|
|
|
|
C< -bareword > names will be interpreted as C< $bareword > which can cut down
|
203
|
|
|
|
|
|
|
on the number of quotes you need to write (C<< use my say => sub {...}; >>)
|
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
if the name is an C< @array > or C< %hash > the corresponding values must be
|
206
|
|
|
|
|
|
|
C< ARRAY > or C< HASH > references, which will be dereferenced and copied into
|
207
|
|
|
|
|
|
|
the new variables.
|
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
so the above becomes:
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
my $say; BEGIN {$say = here::fetch(1)}
|
212
|
|
|
|
|
|
|
my @array; BEGIN {@array = @{here::fetch(2)}}
|
213
|
|
|
|
|
|
|
my %hash; BEGIN {%hash = %{here::fetch(3)}}
|
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
where C< here::fetch > is a subroutine that returns the values passed into the
|
216
|
|
|
|
|
|
|
declarator, which gets around needing to serialize the values.
|
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
=back
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=head2 [array of names] => list or array of values
|
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
=over 4
|
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
use my [qw($x $y $z)] => 1, 2, 3;
|
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
use my [qw($foo @bar %baz)] => ['FOO', [qw(B A R)], {b => 'az'}];
|
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
this usage is exactly like the list of name/value pairs usage except the names
|
229
|
|
|
|
|
|
|
and values are passed in separately. the names must be an array reference. the
|
230
|
|
|
|
|
|
|
values can be an array reference or a list.
|
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
as a syntactic shortcut, the above two lines could also be written:
|
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
use my '($x, $y, $z)' => 1, 2, 3;
|
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
use my '($foo, @bar, %baz)' => 'FOO', [qw(B A R)], {b => 'az'};
|
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
which of course expands to something equivalent to:
|
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
my ($x, $y, $z);
|
241
|
|
|
|
|
|
|
BEGIN {$x = 1; $y = 2; $z = 3}
|
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
my ($foo, @bar, %baz);
|
244
|
|
|
|
|
|
|
BEGIN {$foo = 'FOO'; @bar = qw(B A R); %baz = (b => 'az')}
|
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
ignoring the complexities of C< here::fetch >
|
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=back
|
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=head2 const and const2
|
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
=over 4
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
use const '$FOO' => 'BAR';
|
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
use const2 DEBUG => 1;
|
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
which expands to:
|
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
our $FOO; BEGIN {*FOO = \'BAR'}
|
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
sub DEBUG () {1} our $DEBUG; BEGIN {*DEBUG = \DEBUG}
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
these declarations only accept C< $scalar >, C< bareword > or C< -bareword >
|
265
|
|
|
|
|
|
|
names (interchangeably), but otherwise the usage is similar to C< use my ... >
|
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
the single argument syntax is not supported with these two declarations.
|
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
=back
|
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=head2 cleanup
|
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=over 4
|
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
you can remove the pseudo-modules manually:
|
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
no here::declare;
|
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
or let the declaration fall out of scope if L is installed:
|
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
{
|
282
|
|
|
|
|
|
|
use here::declare;
|
283
|
|
|
|
|
|
|
use my ...; # works
|
284
|
|
|
|
|
|
|
}
|
285
|
|
|
|
|
|
|
use my ...; # error
|
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=back
|
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
=head1 EXPORT
|
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
if you don't like the installation of pseudo-modules, you can pass
|
292
|
|
|
|
|
|
|
C< use here::declare > a list of any of the pseudo-module names each containing
|
293
|
|
|
|
|
|
|
at least one upper case character. this will cause that name to be exported
|
294
|
|
|
|
|
|
|
into your namespace as a subroutine.
|
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
use here::declare 'MY';
|
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
use here MY [qw($x $y)] => [0, 0];
|
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=head1 SEE ALSO
|
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
C< here::declare > is built on top of the L< here > framework.
|
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
in writing this module, I was pushed by p5p to make the interface a bit closer
|
305
|
|
|
|
|
|
|
to the native C< my > and C< our > keywords. I did this with L
|
306
|
|
|
|
|
|
|
in L. C is certainly closer in usage to the
|
307
|
|
|
|
|
|
|
keywords, but the dependency on C might prevent installation for
|
308
|
|
|
|
|
|
|
some people. in addition, this module (despite using C) is
|
309
|
|
|
|
|
|
|
a little safer to use than C since the C |
310
|
|
|
|
|
|
|
by this module more clearly delineates the scope of its actions.
|
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=head1 AUTHOR
|
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
Eric Strom, C<< >>
|
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
=head1 BUGS
|
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
please report any bugs or feature requests to C, or
|
319
|
|
|
|
|
|
|
through the web interface at L.
|
320
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of progress on
|
321
|
|
|
|
|
|
|
your bug as I make changes.
|
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT
|
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
copyright 2011 Eric Strom.
|
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
this program is free software; you can redistribute it and/or modify it under
|
328
|
|
|
|
|
|
|
the terms of either: the GNU General Public License as published by the Free
|
329
|
|
|
|
|
|
|
Software Foundation; or the Artistic License.
|
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
see http://dev.perl.org/licenses/ for more information.
|
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=cut
|
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
1
|