|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Data::Focus;  | 
| 
2
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
 
 | 
349734
 | 
 use strict;  | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
    | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
824
 | 
    | 
| 
3
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
 
 | 
97
 | 
 use warnings;  | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
    | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
577
 | 
    | 
| 
4
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
 
 | 
8229
 | 
 use Data::Focus::Lens::Composite;  | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
201
 | 
    | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
537
 | 
    | 
| 
5
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
 
 | 
119
 | 
 use Carp;  | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
    | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1807
 | 
    | 
| 
6
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
 
 | 
102
 | 
 use Exporter qw(import);  | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
    | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
527
 | 
    | 
| 
7
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
 
 | 
93
 | 
 use Scalar::Util ();  | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
    | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13090
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = "0.02";  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our @EXPORT_OK = qw(focus);  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub focus {  | 
| 
14
 | 
12775
 | 
 
 | 
 
 | 
  
12775
  
 | 
  
1
  
 | 
236108
 | 
     my ($target, @lenses) = @_;  | 
| 
15
 | 
12775
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27998
 | 
     return __PACKAGE__->new(target => $target, lens => \@lenses);  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
19
 | 
12785
 | 
 
 | 
 
 | 
  
12785
  
 | 
  
1
  
 | 
25889
 | 
     my ($class, %args) = @_;  | 
| 
20
 | 
12785
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
25020
 | 
     croak "target param is mandatory" if !exists($args{target});  | 
| 
21
 | 
12785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13402
 | 
     my $target = $args{target};  | 
| 
22
 | 
12785
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
32627
 | 
     my $lenses = exists($args{lens}) ?  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         (ref($args{lens}) eq "ARRAY" ? $args{lens} : [$args{lens}])  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         : [];  | 
| 
25
 | 
12785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20222
 | 
     $_ = $class->coerce_to_lens($_) foreach @$lenses;  | 
| 
26
 | 
12785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34825
 | 
     my $self = bless {  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         target => $target,  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         lenses => $lenses  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }, $class;  | 
| 
30
 | 
12785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35825
 | 
     return $self;  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub coerce_to_lens {  | 
| 
34
 | 
12860
 | 
 
 | 
 
 | 
  
12860
  
 | 
  
1
  
 | 
14115
 | 
     my (undef, $maybe_lens) = @_;  | 
| 
35
 | 
12860
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
73451
 | 
     if(Scalar::Util::blessed($maybe_lens) && $maybe_lens->isa("Data::Focus::Lens")) {  | 
| 
36
 | 
12814
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33806
 | 
         return $maybe_lens;  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }else {  | 
| 
38
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
632
 | 
         require Data::Focus::Lens::HashArray::Index;  | 
| 
39
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
203
 | 
         return Data::Focus::Lens::HashArray::Index->new(index => $maybe_lens); ## default lens (for now)  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub into {  | 
| 
44
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
1
  
 | 
17
 | 
     my ($self, @lenses) = @_;  | 
| 
45
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     unshift @lenses, @{$self->{lenses}};  | 
| 
 
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
    | 
| 
46
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     my $deeper = ref($self)->new(  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         target => $self->{target},  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         lens => \@lenses,  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
50
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     return $deeper;  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _apply_lenses_to_target {  | 
| 
54
 | 
12820
 | 
 
 | 
 
 | 
  
12820
  
 | 
 
 | 
17672
 | 
     my ($self, $app_class, $updater, @additional_lenses) = @_;  | 
| 
55
 | 
12820
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10279
 | 
     my @lenses = (@{$self->{lenses}}, map { $self->coerce_to_lens($_) } @additional_lenses);  | 
| 
 
 | 
12820
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21707
 | 
    | 
| 
 
 | 
12804
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19223
 | 
    | 
| 
56
 | 
12820
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19049
 | 
     if(@lenses == 1) {  | 
| 
57
 | 
12737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34877
 | 
         return $lenses[0]->apply_lens(  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $app_class, $app_class->create_part_mapper($updater), $self->{target}  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }else {  | 
| 
61
 | 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
340
 | 
         return Data::Focus::Lens::Composite->apply_composite_lens(  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             \@lenses,  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $app_class,  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $app_class->create_part_mapper($updater),  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $self->{target}  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         );  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get {  | 
| 
71
 | 
399
 | 
 
 | 
 
 | 
  
399
  
 | 
  
1
  
 | 
3175
 | 
     my ($self, @lenses) = @_;  | 
| 
72
 | 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9454
 | 
     require Data::Focus::Applicative::Const::First;  | 
| 
73
 | 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
843
 | 
     my $ret = $self->_apply_lenses_to_target(  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         "Data::Focus::Applicative::Const::First", undef, @lenses  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     )->get_const;  | 
| 
76
 | 
399
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2562
 | 
     return defined($ret) ? $$ret : undef;  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub list {  | 
| 
80
 | 
562
 | 
 
 | 
 
 | 
  
562
  
 | 
  
1
  
 | 
826
 | 
     my ($self, @lenses) = @_;  | 
| 
81
 | 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10346
 | 
     require Data::Focus::Applicative::Const::List;  | 
| 
82
 | 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1187
 | 
     my $traversed_list = $self->_apply_lenses_to_target(  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         "Data::Focus::Applicative::Const::List", undef, @lenses  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     )->get_const;  | 
| 
85
 | 
562
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4089
 | 
     return wantarray ? @$traversed_list : $traversed_list->[0];  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub over {  | 
| 
89
 | 
11859
 | 
 
 | 
 
 | 
  
11859
  
 | 
  
1
  
 | 
10502
 | 
     my $updater = pop;  | 
| 
90
 | 
11859
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14390
 | 
     my ($self, @lenses) = @_;  | 
| 
91
 | 
11859
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
21257
 | 
     croak "updater param must be a code-ref" if ref($updater) ne "CODE";  | 
| 
92
 | 
11859
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56431
 | 
     require Data::Focus::Applicative::Identity;  | 
| 
93
 | 
11859
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20585
 | 
     return $self->_apply_lenses_to_target(  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         "Data::Focus::Applicative::Identity", $updater, @lenses  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     )->run_identity;  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub set {  | 
| 
99
 | 
11837
 | 
 
 | 
 
 | 
  
11837
  
 | 
  
1
  
 | 
14537
 | 
     my $datum = pop;  | 
| 
100
 | 
11837
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10032
 | 
     my $self = shift;  | 
| 
101
 | 
11837
 | 
 
 | 
 
 | 
  
17176
  
 | 
 
 | 
37240
 | 
     return $self->over(@_, sub { $datum });  | 
| 
 
 | 
17176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37142
 | 
    | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |