File Coverage

blib/lib/JSON/Path.pm
Criterion Covered Total %
statement 82 88 93.1
branch 9 14 64.2
condition 7 9 77.7
subroutine 24 24 100.0
pod 11 11 100.0
total 133 146 91.1


line stmt bran cond sub pod time code
1 13     13   1862443 use 5.008;
  13         142  
2 13     13   68 use strict;
  13         25  
  13         288  
3 13     13   67 use warnings;
  13         39  
  13         751  
4              
5             package JSON::Path;
6             $JSON::Path::VERSION = '0.5';
7             # VERSION
8              
9 13     13   6564 use Exporter::Tiny ();
  13         42772  
  13         687  
10             our @ISA = qw/ Exporter::Tiny /;
11             our $AUTHORITY = 'cpan:POPEFELIX';
12             our $Safe = 1;
13              
14 13     13   108 use Carp;
  13         24  
  13         832  
15 13     13   6810 use JSON::MaybeXS qw/decode_json/;
  13         94032  
  13         745  
16 13     13   7622 use JSON::Path::Evaluator;
  13         47  
  13         830  
17 13     13   94 use Scalar::Util qw[blessed];
  13         26  
  13         644  
18 13     13   6401 use LV ();
  13         50427  
  13         674  
19              
20             our @EXPORT_OK = qw/ jpath jpath1 jpath_map /;
21              
22 13     13   101 use overload '""' => \&to_string;
  13         23  
  13         127  
23              
24             sub jpath {
25 3     3 1 10 my ( $object, $expression ) = @_;
26 3         11 my @return = __PACKAGE__->new($expression)->values($object);
27             }
28              
29             sub jpath1 : lvalue {
30 4     4 1 1569 my ( $object, $expression ) = @_;
31 4         20 __PACKAGE__->new($expression)->value($object);
32             }
33              
34             sub jpath_map (&$$) {
35 1     1 1 191 my ( $coderef, $object, $expression ) = @_;
36 1         6 return __PACKAGE__->new($expression)->map( $object, $coderef );
37             }
38              
39             sub new {
40 32     32 1 11609 my ( $class, $expression ) = @_;
41 32 50 33     187 return $expression
42             if blessed($expression) && $expression->isa(__PACKAGE__);
43 32         139 return bless \$expression, $class;
44             }
45              
46             sub to_string {
47 71     71 1 219 my ($self) = @_;
48 71         626 return $$self;
49             }
50              
51             sub paths {
52 6     6 1 1942 my ( $self, $object ) = @_;
53 6         158 my @paths = JSON::Path::Evaluator::evaluate_jsonpath( $object, "$self", want_path => 1);
54 6         32 return @paths;
55             }
56              
57             sub get {
58 9     9 1 32 my ( $self, $object ) = @_;
59 9         34 my @values = $self->values($object);
60 9 100       40 return wantarray ? @values : $values[0];
61             }
62              
63             sub set {
64 10     10 1 820 my ( $self, $object, $value, $limit ) = @_;
65              
66 10 50       35 if ( !ref $object ) {
67             # warn if not called internally. If called internally (i.e. from value()) we will already have warned.
68 0         0 my @c = caller(0);
69 0 0       0 if ( $c[1] !~ /JSON\/Path\.pm$/ ) {
70 0         0 carp qq{Useless attempt to set a value on a non-reference};
71             }
72             }
73 10         20 my $count = 0;
74 10         77 my @refs = JSON::Path::Evaluator::evaluate_jsonpath( $object, "$self", want_ref => 1 );
75 10         28 for my $ref (@refs) {
76 12         24 ${$ref} = $value;
  12         21  
77 12         22 ++$count;
78 12 100 100     54 last if $limit && ( $count >= $limit );
79             }
80 10         46 return $count;
81             }
82              
83             sub value : lvalue {
84 13     13 1 6582 my ( $self, $object ) = @_;
85             LV::lvalue(
86             get => sub {
87 8     8   200 my ($value) = $self->get($object);
88 8         50 return $value;
89             },
90             set => sub {
91 6     6   99 my $value = shift;
92             # do some caller() magic to warn at the right place
93 6 50       42 if ( !ref $object ) {
94 0         0 my @c = caller(2);
95 0         0 my ( $filename, $line ) = @c[ 1, 2 ];
96 0         0 warn qq{Useless attempt to set a value on a non-reference at $filename line $line\n};
97             }
98 6         21 $self->set( $object, $value, 1 );
99             },
100 13         137 );
101             }
102              
103             sub values {
104 27     27 1 1409 my ( $self, $object ) = @_;
105 27 100 100     315 croak q{non-safe evaluation, died} if "$self" =~ /\?\(/ && $JSON::Path::Safe;
106              
107 26         63 return JSON::Path::Evaluator::evaluate_jsonpath( $object, "$self", script_engine => 'perl' );
108             }
109              
110             sub map {
111 1     1 1 3 my ( $self, $object, $coderef ) = @_;
112 1         2 my $count;
113 1         4 foreach my $path ( $self->paths( $object ) ) {
114 4         10 my ($ref) = JSON::Path::Evaluator::evaluate_jsonpath( $object, $path, want_ref => 1 );
115 4         7 ++$count;
116 4         4 my $value = do {
117 13     13   10497 no warnings 'numeric';
  13         31  
  13         1595  
118 4         7 local $_ = ${$ref};
  4         7  
119 4         13 local $. = $path;
120 4         22 scalar $coderef->();
121             };
122 4         20 ${$ref} = $value;
  4         10  
123             }
124 1         4 return $count;
125             }
126              
127             1;
128              
129             __END__