File Coverage

blib/lib/URI/PathAbstract.pm
Criterion Covered Total %
statement 93 99 93.9
branch 37 44 84.0
condition 6 10 60.0
subroutine 20 22 90.9
pod 7 7 100.0
total 163 182 89.5


line stmt bran cond sub pod time code
1             package URI::PathAbstract;
2              
3 3     3   194891 use strict;
  3         9  
  3         111  
4 3     3   18 use warnings;
  3         5  
  3         150  
5              
6             =head1 NAME
7              
8             URI::PathAbstract - A URI-like object with Path::Abstract capabilities
9              
10             =head1 VERSION
11              
12             Version 0.01
13              
14             =cut
15              
16             our $VERSION = '0.01';
17              
18             =head1 SYNOPSIS
19              
20             my $uri = URI::PathAbstract->new("http://example.com?a=b")
21              
22             $uri->down("apple")
23             # http://example.com/apple?a=b
24              
25             $uri->query("c=d&e=f")
26             # http://example.com/apple?c=d&e=f
27              
28             $uri->path("grape/blueberry/pineapple")
29             # http://example.com/grape/blueberry/pineapple?c=d&e=f
30              
31             $uri = $uri->parent
32             # http://example.com/grape/blueberry?c=d&e=f
33              
34             $uri = $uri->child("xyzzy")
35             # http://example.com/grape/blueberry/xyzzy?c=d&e=f
36              
37             =head1 DESCRIPTION
38              
39             URI::PathAbstract is a combination of the L and L classes. It is essentially a URI
40             class that delegates path-handling methods to Path::Abstract
41              
42             Unfortunately, this is not true:
43              
44             URI::PathAbstract->new( http://example.com )->isa( URI )
45              
46             URI::PathAbstract supports the L generic and common methods
47              
48             =cut
49              
50 3     3   5037 use URI;
  3         24699  
  3         97  
51 3     3   4383 use Path::Abstract;
  3         268970  
  3         30  
52 3     3   649 use Scalar::Util qw/blessed/;
  3         7  
  3         162  
53 3     3   16 use Carp;
  3         8  
  3         356  
54              
55             use overload
56 57     57   2422 '""' => sub { $_[0]->{uri}->as_string },
57 0     0   0 '==' => sub { overload::StrVal($_[0]) eq overload::StrVal($_[1]) },
58 3         53 fallback => 1,
59 3     3   18 ;
  3         6  
60              
61             =head1 METHODS
62              
63             =head2 URI::PathAbstract->new( , ... )
64              
65             Create a new URI::PathAbstract object based on
66              
67             should be of the L class or some sort of URI-like string
68              
69             =head2 URI::PathAbstract->new( , path => , ... )
70              
71             Create a new URI::PathAbstract object based on but overriding the path with
72              
73             URI::PathAbstract->new("http://example.com/cherry?a=b", path => "grape/lemon")
74             # http://example.com/grape/lemon?a=b"
75              
76             =head2 URI::PathAbstract->new( , child => , ... )
77              
78             Create a new URI::PathAbstract object based on but modifying the path by
79              
80             URI::PathAbstract->new("http://example.com/cherry?a=b", child => "grape/lemon")
81             # http://example.com/cherry/grape/lemon?a=b"
82              
83             =head2 URI::PathAbstract->new( ... )
84              
85             Create a new URI::PathAbstract object based on the following:
86              
87             uri The URI you want to represent
88              
89             base A base URI for use with ->abs and ->rel
90              
91             path A path that will override the path of the given uri
92             (although the scheme, host, ... will remain the same)
93              
94             child A path that will be appended to the path of the given uri
95              
96             =cut
97              
98             sub new {
99 41     41 1 3968 my $self = bless {}, shift;
100              
101 41         149 my %given;
102 41 100       126 if (@_ == 1 ) {
    100          
    50          
103 23         45 $self->uri(shift);
104             }
105             elsif (@_ % 2) {
106 5         17 $self->uri(shift);
107 5         16 %given = @_;
108             }
109             elsif (@_) {
110 13         38 %given = @_;
111 13         38 $self->uri(delete $given{uri});
112             }
113             else {
114 0         0 $self->uri(URI->new);
115             }
116              
117 41 100       96 if (%given) {
118 16 100       40 $self->path($given{path}) if defined $given{path};
119 16 100       61 $self->down($given{child}) if defined $given{child};
120 16 100       59 $self->base($given{base}) if defined $given{base};
121             }
122              
123 41         181 return $self;
124             }
125              
126             =head2 $uri->uri
127              
128             Returns a L object that is a copy (not a reference) of the URI object inside $uri
129              
130             =cut
131              
132             sub uri {
133 72     72 1 89 my $self = shift;
134 72 100       149 if (@_) {
135 41         50 my $uri = shift;
136 41 100       162 $uri = URI->new($uri) unless blessed $uri;
137 41         20507 $self->_path($uri->path);
138 41         135 $self->{uri} = $uri->clone;
139             }
140 72 100       420 return unless defined wantarray;
141 31 50       124 return $self->{uri}->clone unless @_;
142             }
143              
144             =head2 $uri->path
145              
146             Returns a L object that is a copy (not a reference) of the Path::Abstract object inside $uri
147              
148             =head2 $uri->path( )
149              
150             Sets the path of $uri, completely overwriting what was there before
151              
152             The rest of $uri (host, port, scheme, query, ...) does not change
153              
154             =cut
155              
156             sub path {
157 18     18 1 1165 my $self = shift;
158 18 100       44 if (@_) {
159 15         35 my $path = $self->_path(@_);
160 15         60 $self->{uri}->path($path->get);
161             }
162 18 100       594 return unless defined wantarray;
163 3         14 return $self->{path}->clone;
164             }
165              
166             sub _path {
167 56     56   785 my $self = shift;
168 56         108 my @path = @_;
169 56 50       136 @path = @{ $path[0] } if ref $path[0] eq "ARRAY";
  0         0  
170 56         213 my $path = Path::Abstract->new(@path);
171 56         2092 $self->{path} = $path;
172             }
173              
174             =head2 $uri->clone
175              
176             Returns a URI::PathAbstract that is an exact clone of $uri
177              
178             =cut
179              
180             sub clone {
181 22     22 1 101 my $self = shift;
182 22         27 my $class = ref $self;
183 22         43 return $class->new($self->uri);
184             }
185              
186             =head2 $uri->base
187              
188             Returns a L object that is a copy (not a reference) of the base for $uri
189              
190             Returns undef if $uri does not have a base uri
191              
192             =head2 $uri->base( )
193              
194             Sets the base of $uri to
195              
196             =cut
197              
198             sub base {
199 31     31 1 38 my $self = shift;
200 31 100       65 if (@_) {
201 13         15 my $base = shift;
202 13 50       25 if (defined $base) {
203 13         16 my $class = ref $self;
204 13 50 33     131 $base = $base->abs if blessed $base && ($base->isa(__PACKAGE__) || $base->isa('URI::WithBase'));
      66        
205 13 100       64 $base = $class->new(uri => "$base") unless $base->isa(__PACKAGE__);
206             }
207 13         25 $self->{base} = $base;
208             }
209 31 100       72 return unless defined wantarray;
210 18 100       75 return undef unless defined $self->{base};
211 9         22 return $self->{base}->clone;
212             }
213              
214             =head2 $uri->abs
215              
216             =head2 $uri->abs( [ ] )
217              
218             Returns a L object that is the absolute URI formed by combining $uri and
219              
220             If is not given, then $uri->base is used as the base
221              
222             If is not given and $uri->base does not exist, then a clone of $uri is returned
223              
224             See L and L for more C information
225              
226             =cut
227              
228             sub abs {
229 15     15 1 22 my $self = shift;
230 15         23 my $class = ref $self;
231 15   100     56 my $base = shift || $self->base || return $self->clone;
232 6         31 return $class->new(uri => $self->uri->abs("$base", @_), base => $base);
233             }
234              
235             =head2 $uri->rel
236              
237             =head2 $uri->rel( [ ] )
238              
239             Returns a L object that is the relative URI formed by comparing $uri and
240              
241             If is not given, then $uri->base is used as the base
242              
243             If is not given and $uri->base does not exist, then a clone of $uri is returned
244              
245             See L and L for more C information
246              
247             =cut
248              
249             sub rel {
250 3     3 1 5 my $self = shift;
251 3         5 my $class = ref $self;
252 3   50     11 my $base = shift || $self->base || return $self->clone;
253 3         16 return $class->new(uri => $self->uri->rel("$base", @_), base => $base);
254             }
255              
256             {
257              
258             =head2 URI
259              
260             See L for more information
261              
262             =head2 ->scheme
263              
264             =head2 ->fragment
265              
266             =head2 ->as_string
267              
268             =head2 ->canonical
269              
270             =head2 ->eq
271              
272             =head2 ->authority
273              
274             =head2 ->query
275              
276             =head2 ->query_form
277              
278             =head2 ->query_keywords
279              
280             =head2 ->userinfo
281              
282             =head2 ->host
283              
284             =head2 ->port
285              
286             =head2 ->host_port
287              
288             =head2 ->default_port
289              
290             =cut
291              
292 3     3   9133 no strict 'refs';
  3         11  
  3         1953  
293              
294             for my $method (grep { ! /^\s*#/ } split m/\n/, <<_END_) {
295             scheme
296             fragment
297             as_string
298             canonical
299             eq
300             authority
301             query
302             query_form
303             query_keywords
304             userinfo
305             host
306             port
307             host_port
308             default_port
309             _END_
310             *$method = sub {
311 1     1   493 my $self = shift;
312 1         15 return $self->{uri}->$method(@_);
313             }
314             }
315              
316             #=head2 abs
317              
318             #Returns a L object
319              
320             #=head2 rel
321              
322             #Returns a L object
323              
324             #=cut
325              
326             =head2 ->opaque
327              
328             =head2 ->path_query
329              
330             =head2 ->path_segments
331              
332             =head2 Path::Abstract
333              
334             See L for more information
335              
336             =head2 ->child
337              
338             =head2 ->parent
339              
340             =cut
341              
342             for my $method (grep { ! /^\s*#/ } split m/\n/, <<_END_) {
343             child
344             parent
345             _END_
346             *$method = sub {
347 4     4   1328 my $self = shift;
348 4         33 my $path = $self->{path}->$method(@_);
349 4         224 my $clone = $self->clone;
350 4         12 $clone->path($path);
351 4         14 return $clone;
352             }
353             }
354              
355             =head2 ->up
356              
357             =head2 ->pop
358              
359             =head2 ->down
360              
361             =head2 ->push
362              
363             =head2 ->to_tree
364              
365             =head2 ->to_branch
366              
367             =cut
368              
369             for my $method (grep { ! /^\s*#/ } split m/\n/, <<_END_) {
370             up
371             pop
372             down
373             push
374             to_tree
375             to_branch
376             #set
377             _END_
378             *$method = sub {
379 9     9   2382 my $self = shift;
380 9         16 my $path = $self->{path};
381 9         13 my @result;
382 9 50       22 if (wantarray) {
383 0         0 my @result = $path->$method(@_);
384             }
385             else {
386 9         46 $result[0] = $path->$method(@_);
387             }
388 9         315 $self->path($$path);
389 9 50       42 return wantarray ? @result : $result[0];
390             }
391             }
392            
393             =head2 ->list
394              
395             =head2 ->first
396              
397             =head2 ->last
398              
399             =head2 ->is_empty
400              
401             =head2 ->is_nil
402              
403             =head2 ->is_root
404              
405             =head2 ->is_tree
406              
407             =head2 ->is_branch
408              
409             =cut
410              
411             for my $method (grep { ! /^\s*#/ } split m/\n/, <<_END_) {
412             #get
413             list
414             first
415             last
416             is_empty
417             is_nil
418             is_root
419             is_tree
420             is_branch
421             _END_
422             *$method = sub {
423 0     0     my $self = shift;
424 0           return $self->{path}->$method(@_);
425             }
426             }
427             }
428              
429             =head1 SEE ALSO
430              
431             L
432              
433             L
434              
435             L
436              
437             L
438              
439             L
440              
441             =head1 AUTHOR
442              
443             Robert Krimen, C<< >>
444              
445             =head1 SOURCE
446              
447             You can contribute or fork this project via GitHub:
448              
449             L
450              
451             git clone git://github.com/robertkrimen/uri-pathabstract.git URI-PathAbstract
452              
453             =head1 BUGS
454              
455             Please report any bugs or feature requests to C, or through
456             the web interface at L. I will be notified, and then you'll
457             automatically be notified of progress on your bug as I make changes.
458              
459             =head1 SUPPORT
460              
461             You can find documentation for this module with the perldoc command.
462              
463             perldoc URI::PathAbstract
464              
465              
466             You can also look for information at:
467              
468             =over 4
469              
470             =item * RT: CPAN's request tracker
471              
472             L
473              
474             =item * AnnoCPAN: Annotated CPAN documentation
475              
476             L
477              
478             =item * CPAN Ratings
479              
480             L
481              
482             =item * Search CPAN
483              
484             L
485              
486             =back
487              
488              
489             =head1 ACKNOWLEDGEMENTS
490              
491              
492             =head1 COPYRIGHT & LICENSE
493              
494             Copyright 2008 Robert Krimen, all rights reserved.
495              
496             This program is free software; you can redistribute it and/or modify it
497             under the same terms as Perl itself.
498              
499              
500             =cut
501              
502             1; # End of URI::PathAbstract