File Coverage

blib/lib/Data/Zipper/API.pm
Criterion Covered Total %
statement 25 25 100.0
branch n/a
condition n/a
subroutine 9 9 100.0
pod 4 4 100.0
total 38 38 100.0


line stmt bran cond sub pod time code
1             package Data::Zipper::API;
2             BEGIN {
3 3     3   18390 $Data::Zipper::API::VERSION = '0.02';
4             }
5              
6 3     3   33 use warnings FATAL => 'all';
  3         6  
  3         5184  
7 3     3   2912 use MooseX::Role::Parameterized;
  3         235338  
  3         25  
8 3     3   113893 use namespace::autoclean;
  3         8  
  3         24  
9              
10             parameter 'type' => (
11             required => 1
12             );
13              
14             role {
15              
16 3     3   345 use MooseX::Types::Moose qw( ArrayRef );
  3         6  
  3         62  
17              
18             my $params = shift;
19              
20             requires 'traverse', 'reconstruct';
21              
22             has path => (
23             is => 'bare',
24             isa => ArrayRef[ $params->type ],
25             default => sub { [] },
26             traits => [ 'Array' ],
27             handles => {
28             path => 'elements'
29             }
30             );
31              
32             has focus => (
33             is => 'ro',
34             required => 1
35             );
36              
37             around traverse => sub {
38             my ($traverser, $self, @args) = @_;
39             my ($focus, $path) = $self->$traverser(@args);
40             return $self->meta->new_object(
41             focus => $focus,
42             path => [
43             $path,
44             $self->path
45             ]
46             );
47             };
48              
49             sub set {
50 6     6 1 44004 my ($self, $new_value) = @_;
51 6         38 return $self->meta->new_object(
52             path => [ $self->path ],
53             focus => $new_value
54             )
55             }
56              
57             sub set_via {
58 1     1 1 1359 my ($self, $code) = @_;
59 1         38 local $_ = $self->focus;
60 1         117 $self->set($code->($self->focus));
61             }
62              
63             sub up {
64 8     8 1 3043 my $self = shift;
65 8         349 my ($path, @rest) = $self->path;
66 8         41 return $self->meta->new_object(
67             focus => $self->reconstruct($self->focus, $path),
68             path => \@rest
69             );
70             }
71              
72             sub zip {
73 5     5 1 7621 my $zipper = shift;
74              
75 5         224 while ($zipper->path) {
76 6         25 $zipper = $zipper->up;
77             }
78 5         181 return $zipper->focus;
79             }
80              
81             };
82              
83             1;
84              
85              
86             __END__
87             =pod
88              
89             =encoding utf-8
90              
91             =head1 NAME
92              
93             Data::Zipper::API
94              
95             =head1 SYNOPSIS
96              
97             package Person;
98             use Moose;
99              
100             has name => ( is => 'ro' );
101              
102             package MyApp;
103             use Data::Zipper::MOP;
104              
105             my $person = Person->new( name => 'John' )
106             my $sally = Data::Zipper::MOP->new( focus => $person)
107             ->traverse('name')->set('Sally')
108             ->up
109             ->focus;
110              
111             =head1 ATTRIBUTES
112              
113             =head2 focus
114              
115             Get the value of the current point in the data structure being focused on (as
116             navigated to by L<traverse>)
117              
118             =head1 METHODS
119              
120             =head2 traverse
121              
122             Traverse deeper into the data structure under focus.
123              
124             =head2 up
125              
126             Move "up" a level from the current traversal. Has the effect of unwinding
127             the last traversal.
128              
129             =head2 set
130              
131             Replace the value of the current node with a new value.
132              
133             =head2 set_via
134              
135             Replace the value of the current node by executing a code reference.
136              
137             C<$_> will be bound to the current value of the node during execution, and
138             the code reference will also be passed this via the first argument.
139              
140             =head2 zip
141              
142             Repeatedly moves back up the paths traversed, which has the effect of
143             returning back to the same structure as the original input.
144              
145             =head1 AUTHOR
146              
147             Oliver Charles
148              
149             =head1 COPYRIGHT AND LICENSE
150              
151             This software is copyright (c) 2011 by Oliver Charles <oliver.g.charles@googlemail.com>.
152              
153             This is free software; you can redistribute it and/or modify it under
154             the same terms as the Perl 5 programming language system itself.
155              
156             =cut
157