File Coverage

blib/lib/CGI/Snapp/Dispatch/Regexp.pm
Criterion Covered Total %
statement 28 30 93.3
branch 3 6 50.0
condition n/a
subroutine 6 6 100.0
pod 1 1 100.0
total 38 43 88.3


line stmt bran cond sub pod time code
1             package CGI::Snapp::Dispatch::Regexp;
2              
3 2     2   3316 use parent 'CGI::Snapp::Dispatch';
  2         430  
  2         9  
4 2     2   102 use strict;
  2         2  
  2         37  
5 2     2   7 use warnings;
  2         3  
  2         75  
6              
7 2     2   14 use Carp;
  2         3  
  2         624  
8              
9             our $VERSION = '2.00';
10              
11             # --------------------------------------------------
12              
13             sub dispatch_args
14             {
15 2     2 1 30 my($self, $args) = @_;
16              
17             return
18             {
19 2         27 args_to_new => {},
20             default => '',
21             prefix => '',
22             table =>
23             [
24             qr|/([^/]+)/?| => {names => ['app']},
25             qr|/([^/]+)/([^/]+)/?| => {names => [qw/app rm/]},
26             ],
27             };
28              
29             } # End of dispatch_args.
30              
31             # --------------------------------------------------
32              
33             sub _parse_path
34             {
35 2     2   4 my($self, $http_method, $path_info, $table) = @_;
36              
37 2         8 $self -> log(debug => "_parse_path($path_info, ...)");
38              
39             # Compare each rule in the table with the path_info, and process the 1st match.
40              
41 2         2 my($rule);
42              
43 2         8 for (my $i = 0; $i < scalar @$table; $i += 2)
44             {
45 2         4 $rule = $$table[$i];
46              
47 2 50       5 next if (! defined $rule);
48              
49 2         8 $self -> log(debug => "Trying to match path info '$path_info' against rule '$rule'");
50              
51             # If we find a match, then run with it.
52              
53 2 50       69 if (my @values = ($path_info =~ m#^$rule$#) )
54             {
55 2         6 $self -> log(debug => 'Matched!');
56              
57 2         2 my(%named_args) = %{$$table[++$i]};
  2         9  
58 2         6 my($names) = delete $named_args{names};
59 2 50       12 @named_args{@$names} = @values if (ref $names eq 'ARRAY');
60              
61 2         8 return {%named_args};
62             }
63             }
64              
65             # No rule matched the given path info.
66              
67 0           $self -> log(debug => 'Nothing matched');
68              
69 0           return {};
70              
71             } # End of _parse_path.
72              
73             # --------------------------------------------------
74              
75             1;
76              
77             =pod
78              
79             =head1 NAME
80              
81             CGI::Snapp::Dispatch::Regexp - Dispatch requests to CGI::Snapp-based objects
82              
83             =head1 Synopsis
84              
85             I
86              
87             use CGI::Snapp::Dispatch::Regexp;
88              
89             CGI::Snapp::Dispatch::Regexp -> new -> dispatch
90             (
91             prefix => 'MyApp',
92             table =>
93             [
94             qr|/([^/]+)/?| => { names => ['app'] },
95             qr|/([^/]+)/([^/]+)/?| => { names => [qw(app rm)] },
96             qr|/([^/]+)/([^/]+)/page(\d+)\.html?| => { names => [qw(app rm page)] },
97             ],
98             );
99              
100             This would also work in a PSGI context. I
101              
102             CGI::Snapp::Dispatch::Regexp -> new -> as_psgi
103             (
104             ...
105             );
106              
107             See t/psgi.regexp.t and t/regexp.t.
108              
109             This usage of new(), so unlike L, is dicussed in L.
110              
111             =head1 Description
112              
113             CGI::Snapp::Dispatch::Regexp is a sub-class of L which overrides 2 methods:
114              
115             =over 4
116              
117             =item o dispatch_args()
118              
119             =item o _parse_path()
120              
121             =back
122              
123             The point is to allow you to use regexps as rules to match the path info, whereas L always
124             assumes your rules are strings.
125              
126             See L for more detail.
127              
128             =head1 Distributions
129              
130             This module is available as a Unix-style distro (*.tgz).
131              
132             See L
133             for help on unpacking and installing distros.
134              
135             =head1 Installation
136              
137             Install L as you would for any C module:
138              
139             Run:
140              
141             cpanm CGI::Snapp::Dispatch
142              
143             or run:
144              
145             sudo cpan CGI::Snapp::Dispatch
146              
147             or unpack the distro, and then either:
148              
149             perl Build.PL
150             ./Build
151             ./Build test
152             sudo ./Build install
153              
154             or:
155              
156             perl Makefile.PL
157             make (or dmake or nmake)
158             make test
159             make install
160              
161             =head1 Constructor and Initialization
162              
163             C is called as C<< my($app) = CGI::Snapp::Dispatch::Regexp -> new(k1 => v1, k2 => v2, ...) >>.
164              
165             It returns a new object of type C.
166              
167             This module accepts exactly the same parameters as does L.
168              
169             See L for details.
170              
171             =head1 Methods
172              
173             =head2 dispatch_args($args)
174              
175             Returns a hashref of args to be used by L or
176             L.
177              
178             Default output:
179              
180             {
181             args_to_new => {},
182             default => '',
183             prefix => '',
184             table =>
185             [
186             qr|/([^/]+)/?| => {names => ['app']},
187             qr|/([^/]+)/([^/]+)/?| => {names => [qw/app rm/]},
188             ],
189             };
190              
191             The differences between this structure and what's used by L are discussed in the L.
192              
193             =head1 FAQ
194              
195             =head2 Is there any sample code?
196              
197             Yes. See t/psgi.regexp.t and t/regexp.t.
198              
199             This module works with both L and L.
200              
201             =head2 What is the structure of the dispatch table?
202              
203             Basically it's the same as in L.
204              
205             The important difference is in the I key, which can be seen just above, under L.
206              
207             The pairs of elements in the I, compared to what's handled by L are:
208              
209             =over 4
210              
211             =item o A regexp instead of a string
212              
213             =item o A hashref with a key of I and an array ref of field names
214              
215             =back
216              
217             See the L for a more complex example.
218              
219             =head1 Troubleshooting
220              
221             See L.
222              
223             =head1 Machine-Readable Change Log
224              
225             The file Changes was converted into Changelog.ini by L.
226              
227             =head1 Version Numbers
228              
229             Version numbers < 1.00 represent development versions. From 1.00 up, they are production versions.
230              
231             =head1 Credits
232              
233             See L. This module is a fork of that code.
234              
235             =head1 Support
236              
237             Email the author, or log a bug on RT:
238              
239             L.
240              
241             =head1 Author
242              
243             L was written by Ron Savage Iron@savage.net.auE> in 2012.
244              
245             Home page: L.
246              
247             =head1 Copyright
248              
249             Australian copyright (c) 2012, Ron Savage.
250              
251             All Programs of mine are 'OSI Certified Open Source Software';
252             you can redistribute them and/or modify them under the terms of
253             The Artistic License, a copy of which is available at:
254             http://www.opensource.org/licenses/index.html
255              
256             =cut