File Coverage

blib/lib/Catmandu/Emit.pm
Criterion Covered Total %
statement 85 102 83.3
branch 15 28 53.5
condition 2 5 40.0
subroutine 21 23 91.3
pod n/a
total 123 158 77.8


line stmt bran cond sub pod time code
1              
2             # eval context ->
3             use Catmandu::Sane;
4 147     147   79980  
  147         332  
  147         1092  
5             our $VERSION = '1.2019';
6              
7             use Catmandu::Util qw(:is :string require_package);
8 147     147   1024 use Clone qw(clone);
  147         321  
  147         40702  
9 147     147   1062 require Catmandu; # avoid circular dependencies
  147         302  
  147         13159  
10              
11             eval $_[0];
12             }
13 1100     1100   207902  
14             # <- eval context
15              
16             use B ();
17             use Moo::Role;
18 147     147   1058  
  147         344  
  147         2900  
19 147     147   745 # global state ->
  147         341  
  147         1244  
20             state $reject = {};
21             }
22              
23 955     955   2147 state $num_labels = 0;
24             my $label = "__CATMANDU__FIX__${num_labels}";
25             $num_labels++;
26             $label;
27 960     960   1358 }
28 960         1900  
29 960         1371 state $reject_label = _generate_label;
30 960         2083 }
31              
32             state $num_vars = 0;
33             my $var = "\$__catmandu__${num_vars}";
34 503     503   1285 $num_vars++;
35             $var;
36             }
37              
38 5147     5147   8729 # <- global state
39 5147         8204  
40 5147         6254 my ($self, @args) = @_;
41 5147         8886 local $@;
42             _eval_emit($self->_emit_sub(@args)) or Catmandu::Error->throw($@);
43             }
44              
45             my ($self, $body, %opts) = @_;
46             my $captures = $opts{captures} ||= {};
47 1100     1100   12744 my $perl = "sub {";
48 1100         1663 if (my $args = $opts{args}) {
49 1100 50       2551 $perl .= 'my (' . join(', ', @$args) . ') = @_;';
50             }
51             $perl .= $body;
52             $perl .= "};";
53 1100     1100   3047 my @captured_vars = map {
54 1100   100     3141 $self->_emit_declare_vars($_,
55 1100         1496 '$_[1]->{' . $self->_emit_string($_) . '}');
56 1100 50       2232 } keys %$captures;
57 1100         3283 $perl = join('', @captured_vars, $perl);
58              
59 1100         2018 return $perl, $captures;
60 1100         1587 }
61              
62 1100         2812 my ($self, $var, $val) = @_;
  1910         3420  
63             $var = "(" . join(", ", @$var) . ")" if is_array_ref($var);
64             $val = "(" . join(", ", @$val) . ")" if is_array_ref($val);
65 1100         3320 if (defined $val) {
66             return "my ${var} = ${val};";
67 1100         3431 }
68             "my ${var};";
69             }
70              
71 2592     2592   4197 my ($self, $test, $pass, $fail) = @_;
72 2592 50       5314 "if (${test}) {${pass}} else {${fail}}";
73 2592 50       4418 }
74 2592 50       3988  
75 2592         8439 my ($self, $sub_var, @args) = @_;
76             "${sub_var}->(" . join(', ', @args) . ")";
77 0         0 }
78              
79             my ($self, $var, $cb) = @_;
80             my $perl = "";
81 145     145   361 my $i = $self->_generate_var;
82 145         631  
83             # loop backwards so that deletions are safe
84             $perl .= "for (my ${i} = \@{${var}} - 1; ${i} >= 0; ${i}--) {";
85             $perl .= $cb->("${var}->[${i}]", up_var => $var, index => $i);
86 702     702   2365 $perl .= "}";
87 702         2796 $perl;
88             }
89              
90             my ($self, $var, $cb) = @_;
91 37     37   116 my $perl = "";
92 37         74 my $k = $self->generate_var;
93 37         87  
94             $perl .= "for my ${k} (keys(\%{${var}})) {";
95             $perl .= $cb->("${var}->{${k}}", up_var => $var, key => $k);
96 37         171 $perl .= "}";
97 37         225 $perl;
98 37         131 }
99 37         105  
100             my ($self, $var, $cb_var, %opts) = @_;
101             my $val_var = $self->_generate_var;
102             my $cancel_var = $self->_generate_var;
103 0     0   0 my $delete_var = $self->_generate_var;
104 0         0 my $perl = "";
105 0         0 $perl
106             .= "my (${val_var}, ${cancel_var}, ${delete_var}) = ${cb_var}->(${var});";
107 0         0 $perl .= "if (${delete_var}) {";
108 0         0 $perl .= $self->_emit_delete(%opts);
109 0         0 $perl .= "} elsif (!${cancel_var}) {";
110 0         0 $perl .= $self->_emit_assign($var, $val_var, %opts);
111             $perl .= "}";
112             $perl;
113             }
114 169     169   535  
115 169         421 my ($self, $var, $val, %opts) = @_;
116 169         384 my $l_var = $var;
117 169         324 if (my $up_var = $opts{up_var}) {
118 169         274 if (defined(my $key = $opts{key})) {
119 169         554 $l_var = "${up_var}->{${key}}";
120             }
121 169         368 elsif (defined(my $index = $opts{index})) {
122 169         486 $l_var = "${up_var}->[${index}]";
123 169         471 }
124 169         512 else {
125 169         271 Catmandu::BadArg->throw('up_var without key or index');
126 169         831 }
127             }
128             "${l_var} = ${val};";
129             }
130 726     726   1558  
131 726         1049 my ($self, %opts) = @_;
132 726 100       1644 my $up_var = $opts{up_var};
133 167 100       437 if (!defined($up_var)) {
    50          
134 155         412  
135             # TODO deleting the root object is equivalent to reject
136             $self->_emit_reject;
137 12         39 }
138             elsif (defined(my $key = $opts{key})) {
139             "delete ${up_var}->{${key}}";
140 0         0 }
141             elsif (defined(my $idx = $opts{index})) {
142             "splice(\@{${up_var}}, ${idx}, 1)";
143 726         2563 }
144             else {
145             Catmandu::BadArg->throw('up_var without key or index');
146             }
147 169     169   433 }
148 169         310  
149 169 100       573 my ($self, $val) = @_;
    100          
    50          
150              
151             ## undef
152 2         7 return 'undef' unless defined $val;
153              
154             ## numbers
155 155         591 # we don't quote ints and floats unless there are leading
156             # (and for floats trailing) zero's
157             if (is_integer($val)) {
158 12         54 return $val;
159             }
160             if (is_float($val) && $val !~ /0$/) {
161 0         0 return $val;
162             }
163              
164             ## strings
165             $self->_emit_string($val);
166 0     0   0 }
167              
168             my ($self, $str) = @_;
169 0 0       0 B::perlstring($str);
170             }
171              
172             my ($self) = @_;
173             'goto ' . $self->_reject_label . ';';
174 0 0       0 }
175 0         0  
176             1;
177 0 0 0     0  
178 0         0  
179             =pod
180              
181             =head1 NAME
182 0         0  
183             Catmandu::Emit - Role with helper methods for code emitting
184              
185             =cut