File Coverage

blib/lib/Data/Printer.pm
Criterion Covered Total %
statement 126 137 91.9
branch 49 72 68.0
condition 34 48 70.8
subroutine 16 16 100.0
pod 2 2 100.0
total 227 275 82.5


line stmt bran cond sub pod time code
1             package Data::Printer;
2 8     8   4568 use strict;
  8         19  
  8         256  
3 8     8   46 use warnings;
  8         26  
  8         209  
4 8     8   4512 use Data::Printer::Object;
  8         30  
  8         299  
5 8     8   58 use Data::Printer::Common;
  8         19  
  8         158  
6 8     8   40 use Data::Printer::Config;
  8         16  
  8         1740  
7              
8             our $VERSION = '1.001000';
9             $VERSION = eval $VERSION;
10              
11             my $rc_arguments;
12             my %arguments_for;
13              
14             sub import {
15 10     10   118 my $class = shift;
16              
17 10         32 _initialize();
18              
19 10         37 my $args;
20 10 100       37 if (@_ > 0) {
21 8 50       78 $args = @_ == 1 ? shift : {@_};
22 8 50       46 Data::Printer::Common::_warn(
23             undef,
24             'Data::Printer can receive either a hash or a hash reference'
25             ) unless ref $args eq 'HASH';
26             $args = Data::Printer::Config::_expand_profile($args)
27 8 50       42 if exists $args->{profile};
28             }
29              
30             # every time you load it, we override the version from *your* caller
31 10         27 my $caller = caller;
32 10         24 $arguments_for{$caller} = $args;
33              
34 10         28 my $use_prototypes = _find_option('use_prototypes', $args, $caller, 1);
35 10 100       34 my $exported = ($use_prototypes ? \&p : \&_p_without_prototypes);
36              
37 10         25 my $imported = _find_option('alias', $args, $caller, 'p');
38              
39 8     8   61 { no strict 'refs';
  8         22  
  8         844  
  10         21  
40 10         16 *{"$caller\::$imported"} = $exported;
  10         80  
41 10         24 *{"$caller\::np"} = \&np;
  10         11503  
42             }
43             }
44              
45             sub _initialize {
46             # potential race but worst case is we read it twice :)
47 8     8   72 { no warnings 'redefine'; *_initialize = sub {} }
  8     63   22  
  8         1331  
48              
49             my $rc_filename = Data::Printer::Config::_get_first_rc_file_available();
50             $rc_arguments = Data::Printer::Config::load_rc_file($rc_filename);
51              
52             if (
53             exists $rc_arguments->{'_'}{live_update}
54             && defined $rc_arguments->{'_'}{live_update}
55             && $rc_arguments->{'_'}{live_update} =~ /\A\d+\z/
56             && $rc_arguments->{'_'}{live_update} > 0) {
57             my $now = time;
58             my $last_mod = (stat $rc_filename)[9];
59             {
60 8     8   59 no warnings 'redefine';
  8         25  
  8         10535  
61             *_initialize = sub {
62             if (time - $now > $rc_arguments->{'_'}{live_update}) {
63             my $new_last_mod = (stat $rc_filename)[9];
64             if (defined $new_last_mod && $new_last_mod > $last_mod) {
65             $now = time;
66             $last_mod = $new_last_mod;
67             $rc_arguments = Data::Printer::Config::load_rc_file($rc_filename);
68             if (!exists $rc_arguments->{'_'}{live_update} || !$rc_arguments->{'_'}{live_update}) {
69             *_initialize = sub {};
70             }
71             }
72             }
73             };
74             }
75             }
76             }
77              
78             sub np (\[@$%&];%) {
79 13     13 1 10608 my (undef, %properties) = @_;
80              
81 13         43 _initialize();
82              
83 13         30 my $caller = caller;
84 13         36 my $args_to_use = _fetch_args_with($caller, \%properties);
85 13 50       40 return '' if $args_to_use->{quiet};
86 13         47 my $printer = Data::Printer::Object->new($args_to_use);
87              
88             # force color level 0 on 'auto' colors:
89 13 50       48 if ($printer->colored eq 'auto') {
90 0         0 $printer->{_output_color_level} = 0;
91             }
92              
93 13         42 my $ref = ref $_[0];
94 13 100 100     98 if ($ref eq 'ARRAY' || $ref eq 'HASH' || ($ref eq 'REF' && ref ${$_[0]} eq 'REF')) {
  10   100     80  
      100        
95 3         7 $printer->{_refcount_base}++;
96             }
97 13         47 my $output = $printer->parse($_[0]);
98 13 50       44 if ($printer->caller_message_position eq 'after') {
99 0         0 $output .= $printer->_write_label;
100             }
101             else {
102 13         38 $output = $printer->_write_label . $output;
103             }
104 13         324 return $output;
105             }
106              
107              
108             sub p (\[@$%&];%) {
109 44     44 1 141372 my (undef, %properties) = @_;
110              
111 44         161 _initialize();
112              
113 44         111 my $caller = caller;
114 44         152 my $args_to_use = _fetch_args_with($caller, \%properties);
115 44 50       138 return if $args_to_use->{quiet};
116 44         283 my $printer = Data::Printer::Object->new($args_to_use);
117 44         170 my $want_value = defined wantarray;
118 44 0 33     146 if ($printer->colored eq 'auto' && $printer->return_value eq 'dump' && $want_value) {
      33        
119 0         0 $printer->{_output_color_level} = 0;
120             }
121              
122 44         149 my $ref = ref $_[0];
123 44 100 100     358 if ($ref eq 'ARRAY' || $ref eq 'HASH' || ($ref eq 'REF' && ref ${$_[0]} eq 'REF')) {
  17   100     84  
      100        
124 7         18 $printer->{_refcount_base}++;
125             }
126 44         188 my $output = $printer->parse($_[0]);
127 44 100       151 if ($printer->caller_message_position eq 'after') {
128 1         3 $output .= $printer->_write_label;
129             }
130             else {
131 43         130 $output = $printer->_write_label . $output;
132             }
133              
134 44         215 return _handle_output($printer, $output, $want_value, $_[0]);
135             }
136              
137             # This is a p() clone without prototypes. Just like regular Data::Dumper,
138             # this version expects a reference as its first argument. We make a single
139             # exception for when we only get one argument, in which case we ref it
140             # for the user and keep going.
141             sub _p_without_prototypes {
142 4     4   95 my (undef, %properties) = @_;
143              
144 4         8 my $item;
145 4 100 66     20 if (!ref $_[0] && @_ == 1) {
146 1         3 my $item_value = $_[0];
147 1         2 $item = \$item_value;
148             }
149              
150 4         14 _initialize();
151              
152 4         10 my $caller = caller;
153 4         12 my $args_to_use = _fetch_args_with($caller, \%properties);
154 4 50       24 return if $args_to_use->{quiet};
155 4         25 my $printer = Data::Printer::Object->new($args_to_use);
156              
157 4         9 my $want_value = defined wantarray;
158 4 0 33     12 if ($printer->colored eq 'auto' && $printer->return_value eq 'dump' && $want_value) {
      33        
159 0         0 $printer->{_output_color_level} = 0;
160             }
161              
162 4 100       16 my $ref = ref( defined $item ? $item : $_[0] );
163 4 0 100     35 if ($ref eq 'ARRAY' || $ref eq 'HASH' || ($ref eq 'REF'
    100 33        
      66        
164 0         0 && ref(defined $item ? $item : ${$_[0]}) eq 'REF')) {
165 2         4 $printer->{_refcount_base}++;
166             }
167 4 100       20 my $output = $printer->parse((defined $item ? $item : $_[0]));
168 4 50       13 if ($printer->caller_message_position eq 'after') {
169 0         0 $output .= $printer->_write_label;
170             }
171             else {
172 4         14 $output = $printer->_write_label . $output;
173             }
174              
175 4         15 return _handle_output($printer, $output, $want_value, $_[0]);
176             }
177              
178              
179             sub _handle_output {
180 48     48   161 my ($printer, $output, $wantarray, $data) = @_;
181              
182 48 100 100     150 if ($printer->return_value eq 'pass') {
    100          
183 9         19 print { $printer->{output_handle} } $output . "\n";
  9         682  
184 9         102 require Scalar::Util;
185 9         41 my $ref = Scalar::Util::blessed($data);
186 9 100       66 return $data if defined $ref;
187 8         41 $ref = Scalar::Util::reftype($data);
188 8 50       52 if (!$ref) {
    100          
    100          
    50          
189 0         0 return $data;
190             }
191             elsif ($ref eq 'ARRAY') {
192 2         71 return @$data;
193             }
194             elsif ($ref eq 'HASH') {
195 2         60 return %$data;
196             }
197 12         36 elsif ( grep { $ref eq $_ } qw(REF SCALAR VSTRING) ) {
198 4         221 return $$data;
199             }
200             else {
201 0         0 return $data;
202             }
203             }
204             elsif ($printer->return_value eq 'void' || !$wantarray) {
205 7         12 print { $printer->{output_handle} } $output . "\n";
  7         289  
206 7         336 return;
207             }
208             else {
209 32         985 return $output;
210             }
211             }
212              
213             sub _fetch_args_with {
214 61     61   159 my ($caller, $run_properties) = @_;
215              
216 61         121 my $args_to_use = {};
217 61 50       213 if (keys %$rc_arguments) {
218             $args_to_use = Data::Printer::Config::_merge_options(
219 61         263 $args_to_use, $rc_arguments->{'_'}
220             );
221 61 50       221 if (exists $rc_arguments->{$caller}) {
222             $args_to_use = Data::Printer::Config::_merge_options(
223 0         0 $args_to_use, $rc_arguments->{$caller}
224             );
225             }
226             }
227 61 50       201 if ($arguments_for{$caller}) {
228             $args_to_use = Data::Printer::Config::_merge_options(
229 61         162 $args_to_use, $arguments_for{$caller}
230             );
231             }
232 61 100       204 if (keys %$run_properties) {
233             $run_properties = Data::Printer::Config::_expand_profile($run_properties)
234 15 50       46 if exists $run_properties->{profile};
235 15         44 $args_to_use = Data::Printer::Config::_merge_options(
236             $args_to_use, $run_properties
237             );
238             }
239 61         144 return $args_to_use;
240             }
241              
242              
243             sub _find_option {
244 20     20   53 my ($key, $args, $caller, $default) = @_;
245              
246 20         31 my $value;
247 20 100 33     104 if (exists $args->{$key}) {
    50          
    50          
248 2         4 $value = $args->{$key};
249             }
250             elsif (
251             exists $rc_arguments->{$caller}
252             && exists $rc_arguments->{$caller}{$key}
253             ) {
254 0         0 $value = $rc_arguments->{$caller}{$key};
255             }
256             elsif (exists $rc_arguments->{'_'}{$key}) {
257 0         0 $value = $rc_arguments->{'_'}{$key};
258             }
259             else {
260 18         33 $value = $default;
261             }
262 20         45 return $value;
263             }
264              
265              
266             'Marielle, presente.';
267             __END__