line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Params::Registry; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
1437
|
use 5.010; |
|
1
|
|
|
|
|
4
|
|
4
|
1
|
|
|
1
|
|
16
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
52
|
|
5
|
1
|
|
|
1
|
|
6
|
use warnings FATAL => 'all'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
51
|
|
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
6
|
use Moose; |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
6
|
|
8
|
1
|
|
|
1
|
|
5154
|
use namespace::autoclean; |
|
1
|
|
|
|
|
10
|
|
|
1
|
|
|
|
|
21
|
|
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
96
|
use MooseX::Types::Moose qw(Maybe Str HashRef ArrayRef); |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
36
|
|
11
|
1
|
|
|
1
|
|
6099
|
use Params::Registry::Types qw(Template); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
20
|
|
12
|
|
|
|
|
|
|
|
13
|
1
|
|
|
1
|
|
7177
|
use MooseX::Params::Validate (); |
|
1
|
|
|
|
|
61554
|
|
|
1
|
|
|
|
|
37
|
|
14
|
|
|
|
|
|
|
|
15
|
1
|
|
|
1
|
|
14
|
use Params::Registry::Template; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
21
|
|
16
|
1
|
|
|
1
|
|
6
|
use Params::Registry::Instance; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
22
|
|
17
|
1
|
|
|
1
|
|
7
|
use Params::Registry::Error; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
19
|
|
18
|
|
|
|
|
|
|
|
19
|
1
|
|
|
1
|
|
773
|
use URI; |
|
1
|
|
|
|
|
2765
|
|
|
1
|
|
|
|
|
33
|
|
20
|
1
|
|
|
1
|
|
518
|
use URI::QueryParam; |
|
1
|
|
|
|
|
796
|
|
|
1
|
|
|
|
|
1223
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 NAME |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
Params::Registry - Housekeeping for sets of named parameters |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 VERSION |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
Version 0.09_05 |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=cut |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
our $VERSION = '0.09_05'; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head1 SYNOPSIS |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
use Params::Registry; |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
my $registry = Params::Registry->new( |
39
|
|
|
|
|
|
|
# express the global parameter sequence with an arrayref |
40
|
|
|
|
|
|
|
params => [ |
41
|
|
|
|
|
|
|
{ |
42
|
|
|
|
|
|
|
# see Params::Registry::Template for the full list of |
43
|
|
|
|
|
|
|
# attributes |
44
|
|
|
|
|
|
|
name => 'foo', |
45
|
|
|
|
|
|
|
}, |
46
|
|
|
|
|
|
|
], |
47
|
|
|
|
|
|
|
# specify groups containing potentially-overlapping subsets of |
48
|
|
|
|
|
|
|
# parameters for different aspects of your system |
49
|
|
|
|
|
|
|
groups => { |
50
|
|
|
|
|
|
|
stuff => [qw(foo)], |
51
|
|
|
|
|
|
|
}, |
52
|
|
|
|
|
|
|
# override the name of the special 'complement' parameter |
53
|
|
|
|
|
|
|
complement => 'negate', |
54
|
|
|
|
|
|
|
); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
my $instance = eval { $registry->process(\%params) }; |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
$uri->query($instance->as_string); |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=head1 DESCRIPTION |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
The purpose of this module is to handle a great deal of the |
63
|
|
|
|
|
|
|
housekeeping around sets of named parameters and their values, |
64
|
|
|
|
|
|
|
especially as they pertain to web development. Modules like |
65
|
|
|
|
|
|
|
L<URI::QueryParam> and L<Catalyst> will take a URI query string and |
66
|
|
|
|
|
|
|
turn it into a HASH reference containing either scalars or ARRAY |
67
|
|
|
|
|
|
|
references of values, but further processing is almost always needed |
68
|
|
|
|
|
|
|
to validate the parameters, normalize them, turn them into useful |
69
|
|
|
|
|
|
|
compound objects, and last but not least, serialize them back into a |
70
|
|
|
|
|
|
|
canonical string representation. It is likewise important to be able |
71
|
|
|
|
|
|
|
to encapsulate error reporting around malformed or conflicting input, |
72
|
|
|
|
|
|
|
at both the syntactical and semantic levels. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
While this module was designed with the web in mind, it can be used |
75
|
|
|
|
|
|
|
wherever a global registry of named parameters is deemed useful. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=over 4 |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=item Scalar |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
basically untouched |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=item List |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
basically untouched |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=item Tuple |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
A tuple can be understood as a list of definite length, for which each |
90
|
|
|
|
|
|
|
position has its own meaning. The contents of a tuple can likewise be |
91
|
|
|
|
|
|
|
heterogeneous. |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=item Set |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
A standard mathematical set has no duplicate elements and no concept |
96
|
|
|
|
|
|
|
of sequence. |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=item Range |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
A range can be understood as a span of numbers or number-like objects, |
101
|
|
|
|
|
|
|
such as L<DateTime> objects. |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
=item Object |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
When nothing else will do |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=back |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=head3 Cascading |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
There are instances, for example in the case of supporting a legacy |
112
|
|
|
|
|
|
|
HTML form, when it is useful to combine input parameters. Take for |
113
|
|
|
|
|
|
|
instance the practice of using drop-down boxes for the year, month and |
114
|
|
|
|
|
|
|
day of a date in lieu of support for the HTML5 C<datetime> form field, |
115
|
|
|
|
|
|
|
or access to custom form controls. One would specify C<year>, C<month> |
116
|
|
|
|
|
|
|
and C<day> parameters, as well as a C<date> parameter which |
117
|
|
|
|
|
|
|
C<consumes> the former three, C<using> a subroutine reference to do |
118
|
|
|
|
|
|
|
it. Consumed parameters are deleted from the set. |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=head3 Complement |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
A special parameter, C<complement>, is defined to signal parameters in |
123
|
|
|
|
|
|
|
the set itself which should be treated as complements to what have |
124
|
|
|
|
|
|
|
been expressed in the input. This module makes no prescriptions about |
125
|
|
|
|
|
|
|
how the complement is to be interpreted, with the exception of |
126
|
|
|
|
|
|
|
parameters whose values are bounded sets or ranges: if a shorter query |
127
|
|
|
|
|
|
|
string can be achieved by negating the set and removing (or adding) |
128
|
|
|
|
|
|
|
the parameter's name to the complement, that is what this module will |
129
|
|
|
|
|
|
|
do. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
# universe of foo = (a .. z) |
132
|
|
|
|
|
|
|
foo=a&foo=b&foo=c&complement=foo -> (a .. z) - (a b c) |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=head1 METHODS |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=head2 new |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
Instantiate a new parameter registry. |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=head3 Arguments |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=over 4 |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=item params |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
An C<ARRAY> reference of C<HASH> references, containing the specs to |
147
|
|
|
|
|
|
|
be passed into L<Params::Registry::Template> objects. |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=cut |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
around BUILDARGS => sub { |
152
|
|
|
|
|
|
|
my $orig = shift; |
153
|
|
|
|
|
|
|
my $class = shift; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
my %p = MooseX::Params::Validate::validated_hash( |
156
|
|
|
|
|
|
|
\@_, |
157
|
|
|
|
|
|
|
params => { isa => 'ArrayRef[Maybe[HashRef]]' }, |
158
|
|
|
|
|
|
|
complement => { isa => 'Maybe[Str]', optional => 1 }, |
159
|
|
|
|
|
|
|
groups => { isa => 'HashRef[ArrayRef[Maybe[Str]]]', optional => 1 }, |
160
|
|
|
|
|
|
|
); |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
# fiddle with input and output |
163
|
|
|
|
|
|
|
my @entries = @{delete $p{params}}; |
164
|
|
|
|
|
|
|
$p{params} = {}; |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# pass once to separate the templates from their sequence |
167
|
|
|
|
|
|
|
my (@seq, %map); |
168
|
|
|
|
|
|
|
for my $entry (@entries) { |
169
|
|
|
|
|
|
|
my $name = delete $entry->{name}; |
170
|
|
|
|
|
|
|
push @seq, $name; |
171
|
|
|
|
|
|
|
if (my $use = delete $entry->{use}) { |
172
|
|
|
|
|
|
|
# TODO: recursive |
173
|
|
|
|
|
|
|
$map{$name} = $use; |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
# TODO: throw a proper error on duplicate key |
176
|
|
|
|
|
|
|
Params::Registry::Error->throw |
177
|
|
|
|
|
|
|
("Parameter $name already exists") if exists $p{params}{$name}; |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
$p{params}{$name} = $entry; |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# second pass to stitch the reused parameters together |
183
|
|
|
|
|
|
|
while (my ($k, $v) = each %map) { |
184
|
|
|
|
|
|
|
# TODO throw a proper error if the target isn't found |
185
|
|
|
|
|
|
|
my $p = $p{params}{$v} or Params::Registry::Error->throw |
186
|
|
|
|
|
|
|
("Tried to resolve $v for reuse but couldn't find it"); |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
# overwrite with any new data |
189
|
|
|
|
|
|
|
$p{params}{$k} = {%$p, %{$p{params}{$k}}}; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# add param sequence to BUILD |
193
|
|
|
|
|
|
|
$p{_sequence} = \@seq; |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
$class->$orig(%p); |
196
|
|
|
|
|
|
|
}; |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
sub BUILD { |
199
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
200
|
0
|
|
|
|
|
|
my $p = $self->_params; |
201
|
|
|
|
|
|
|
|
202
|
0
|
|
|
|
|
|
my @seq = @{$self->_sequence}; |
|
0
|
|
|
|
|
|
|
203
|
0
|
|
|
|
|
|
my (%rank, @stack); |
204
|
0
|
|
|
|
|
|
for my $k (@seq) { |
205
|
0
|
|
|
|
|
|
my %t = %{$p->{$k}}; |
|
0
|
|
|
|
|
|
|
206
|
0
|
|
|
|
|
|
my $x = $p->{$k} = Params::Registry::Template->new |
207
|
|
|
|
|
|
|
(%t, registry => $self); |
208
|
0
|
0
|
|
|
|
|
if ($x->_consdep > 0) { |
209
|
|
|
|
|
|
|
# shortcut because only parameters with dependencies will |
210
|
|
|
|
|
|
|
# have a rank higher than zero |
211
|
0
|
|
|
|
|
|
$rank{$k} = 1; |
212
|
0
|
|
|
|
|
|
push @stack, $k; |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
else { |
215
|
0
|
|
|
|
|
|
$rank{$k} = 0; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
# construct a rank tree |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
#my %seen; |
222
|
0
|
|
|
|
|
|
while (my $x = shift @stack) { |
223
|
|
|
|
|
|
|
#my %c = map { $_ => 1 } $p->{$x}->consumes; |
224
|
0
|
|
|
|
|
|
my $match = 0; |
225
|
0
|
|
|
|
|
|
for my $c ($p->{$x}->_consdep) { |
226
|
0
|
0
|
|
|
|
|
$match = 1 if $rank{$x} == $rank{$c}; |
227
|
|
|
|
|
|
|
# XXX will this actually catch all cycles? |
228
|
|
|
|
|
|
|
Params::Registry::Error->throw |
229
|
0
|
0
|
|
|
|
|
("Cycle detected between $x and $c") if $rank{$x} < $rank{$c}; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
0
|
0
|
|
|
|
|
if ($match) { |
233
|
0
|
|
|
|
|
|
$rank{$x}++; |
234
|
0
|
|
|
|
|
|
push @stack, $x; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
# this makes an array of arrays of key names, in the order to be |
239
|
|
|
|
|
|
|
# processed. |
240
|
0
|
|
|
|
|
|
my $r = $self->_ranked; |
241
|
0
|
|
|
|
|
|
for my $k (@seq) { |
242
|
0
|
|
0
|
|
|
|
my $x = $r->[$rank{$k}] ||= []; |
243
|
0
|
|
|
|
|
|
push @$x, $k; |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
# note that any global sequence here would be valid as long as it |
246
|
|
|
|
|
|
|
# didn't put a consuming param before one to be consumed |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# XXX it is currently unclear whether two consuming parameters can |
249
|
|
|
|
|
|
|
# consume the same parameter. |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# we should also do deps and conflicts here: |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
# deps are transitive but asymmetric; A -> B -> C implies A -> C |
254
|
|
|
|
|
|
|
# but says nothing about C |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
# conflicts are symmetric: A conflicts with B means B conflicts |
257
|
|
|
|
|
|
|
# with A. |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# it is nonsensical (and therefore illegal) for parameters to |
260
|
|
|
|
|
|
|
# simultaneously depend and conflict. |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
#warn Data::Dumper::Dumper($self->_ranked); |
263
|
|
|
|
|
|
|
} |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
has _params => ( |
266
|
|
|
|
|
|
|
is => 'ro', |
267
|
|
|
|
|
|
|
#isa => HashRef[Template], |
268
|
|
|
|
|
|
|
isa => HashRef, |
269
|
|
|
|
|
|
|
traits => [qw(Hash)], |
270
|
|
|
|
|
|
|
#coerce => 1, |
271
|
|
|
|
|
|
|
required => 1, |
272
|
|
|
|
|
|
|
init_arg => 'params', |
273
|
|
|
|
|
|
|
handles => { |
274
|
|
|
|
|
|
|
template => 'get', |
275
|
|
|
|
|
|
|
}, |
276
|
|
|
|
|
|
|
); |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
has _sequence => ( |
279
|
|
|
|
|
|
|
is => 'ro', |
280
|
|
|
|
|
|
|
traits => [qw(Array)], |
281
|
|
|
|
|
|
|
isa => ArrayRef[Str], |
282
|
|
|
|
|
|
|
required => 1, |
283
|
|
|
|
|
|
|
handles => { |
284
|
|
|
|
|
|
|
sequence => 'elements', |
285
|
|
|
|
|
|
|
}, |
286
|
|
|
|
|
|
|
); |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
has _ranked => ( |
289
|
|
|
|
|
|
|
is => 'ro', |
290
|
|
|
|
|
|
|
# traits => [qw(Array)], |
291
|
|
|
|
|
|
|
isa => ArrayRef[ArrayRef[Str]], |
292
|
|
|
|
|
|
|
lazy => 1, |
293
|
|
|
|
|
|
|
default => sub { [] }, |
294
|
|
|
|
|
|
|
# required => 1, |
295
|
|
|
|
|
|
|
# handles => { |
296
|
|
|
|
|
|
|
# sequence => 'elements', |
297
|
|
|
|
|
|
|
# }, |
298
|
|
|
|
|
|
|
); |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=item groups |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
A C<HASH> reference such that the keys are names of groups, and the |
303
|
|
|
|
|
|
|
values are C<ARRAY> references of parameters to include in each group. |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=cut |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
has _groups => ( |
308
|
|
|
|
|
|
|
is => 'ro', |
309
|
|
|
|
|
|
|
isa => HashRef[Maybe[ArrayRef[Maybe[Str]]]], |
310
|
|
|
|
|
|
|
lazy => 1, |
311
|
|
|
|
|
|
|
default => sub { {} }, |
312
|
|
|
|
|
|
|
init_arg => 'groups', |
313
|
|
|
|
|
|
|
); |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=item complement |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
This is the I<name> of the special parameter used to indicate which |
318
|
|
|
|
|
|
|
I<other> parameters should have a |
319
|
|
|
|
|
|
|
L<Params::Registry::Template/complement> operation run over them. The |
320
|
|
|
|
|
|
|
default name, naturally, is C<complement>. This parameter will always |
321
|
|
|
|
|
|
|
be added to the query string last. |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=cut |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
has complement => ( |
326
|
|
|
|
|
|
|
is => 'ro', |
327
|
|
|
|
|
|
|
isa => Str, |
328
|
|
|
|
|
|
|
lazy => 1, |
329
|
|
|
|
|
|
|
default => 'complement', |
330
|
|
|
|
|
|
|
); |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=back |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=head2 process $STR | $URI | \%PARAMS |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
Turn a L<URI>, query string or C<HASH> reference (such as those found |
337
|
|
|
|
|
|
|
in L<Catalyst> or L<URI::QueryParam>) into a |
338
|
|
|
|
|
|
|
L<Params::Registry::Instance>. May croak. |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=cut |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
sub process { |
343
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
344
|
|
|
|
|
|
|
|
345
|
0
|
|
|
|
|
|
my $obj; |
346
|
0
|
0
|
0
|
|
|
|
if (ref $_[0]) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
347
|
0
|
0
|
0
|
|
|
|
if (Scalar::Util::blessed($_[0]) and $_[0]->isa('URI')) { |
|
|
0
|
|
|
|
|
|
348
|
0
|
|
|
|
|
|
$obj = $_[0]->query_form_hash; |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
elsif (ref $_[0] eq 'HASH') { |
351
|
0
|
|
|
|
|
|
$obj = $_[0]; |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
else { |
354
|
0
|
|
|
|
|
|
Params::Registry::Error->throw |
355
|
|
|
|
|
|
|
('If the argument is a ref, it must be a URI or a HASH ref'); |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
elsif (@_ == 1 && defined $_[0]) { |
359
|
0
|
|
|
|
|
|
my $x = $_[0]; |
360
|
0
|
0
|
|
|
|
|
$x = "?$x" unless $x =~ /^\?/; |
361
|
0
|
|
|
|
|
|
$obj = URI->new("http://foo/$x")->query_form_hash; |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
elsif (@_ > 0 && @_ % 2 == 0) { |
364
|
0
|
|
|
|
|
|
my %x = @_; |
365
|
0
|
|
|
|
|
|
$obj = \%x; |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
else { |
368
|
0
|
|
|
|
|
|
Params::Registry::Error->throw |
369
|
|
|
|
|
|
|
('Check your inputs to Params::Registry::process'); |
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
0
|
|
|
|
|
|
my $instance = Params::Registry::Instance->new(registry => $self); |
373
|
|
|
|
|
|
|
|
374
|
0
|
|
|
|
|
|
$instance->set($obj, -defaults => 1, -force => 1); |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
=head2 template $KEY |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
Return a particular template from the registry. |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=head2 sequence |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
Return the global sequence of parameters for serialization. |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=head2 refresh |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
Refresh the stateful components of the templates |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=cut |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
sub refresh { |
392
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
393
|
0
|
|
|
|
|
|
for my $template (values %{$self->_params}) { |
|
0
|
|
|
|
|
|
|
394
|
0
|
|
|
|
|
|
$template->refresh; |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=head1 AUTHOR |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
Dorian Taylor, C<< <dorian at cpan.org> >> |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
=head1 BUGS |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
Please report any bugs or feature requests to C<bug-params-registry at |
405
|
|
|
|
|
|
|
rt.cpan.org>, or through the web interface at |
406
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Params-Registry>. I |
407
|
|
|
|
|
|
|
will be notified, and then you'll automatically be notified of |
408
|
|
|
|
|
|
|
progress on your bug as I make changes. |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
=head1 SUPPORT |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
perldoc Params::Registry |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
You can also look for information at: |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
=over 4 |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here) |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Params-Registry> |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
L<http://annocpan.org/dist/Params-Registry> |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=item * CPAN Ratings |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
L<http://cpanratings.perl.org/d/Params-Registry> |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=item * Search CPAN |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
L<http://search.cpan.org/dist/Params-Registry/> |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=back |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
=head1 SEE ALSO |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
=over 4 |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=item |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
L<Params::Registry::Instance> |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
=item |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
L<Params::Registry::Template> |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
=item |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
L<Params::Validate> |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
=back |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
Copyright 2013 Dorian Taylor. |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you |
462
|
|
|
|
|
|
|
may not use this file except in compliance with the License. You may |
463
|
|
|
|
|
|
|
obtain a copy of the License at |
464
|
|
|
|
|
|
|
L<http://www.apache.org/licenses/LICENSE-2.0> . |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software |
467
|
|
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS, |
468
|
|
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
469
|
|
|
|
|
|
|
implied. See the License for the specific language governing |
470
|
|
|
|
|
|
|
permissions and limitations under the License. |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
=cut |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
1; # End of Params::Registry |