File Coverage

blib/lib/Data/Printer.pm
Criterion Covered Total %
statement 126 141 89.3
branch 51 76 67.1
condition 34 48 70.8
subroutine 16 16 100.0
pod 2 2 100.0
total 229 283 80.9


line stmt bran cond sub pod time code
1             package Data::Printer;
2 8     8   4626 use strict;
  8         19  
  8         284  
3 8     8   45 use warnings;
  8         17  
  8         203  
4 8     8   4743 use Data::Printer::Object;
  8         34  
  8         275  
5 8     8   59 use Data::Printer::Common;
  8         15  
  8         173  
6 8     8   76 use Data::Printer::Config;
  8         26  
  8         1715  
7              
8             our $VERSION = '1.001001';
9             $VERSION = eval $VERSION;
10              
11             my $rc_arguments;
12             my %arguments_for;
13              
14             sub import {
15 10     10   103 my $class = shift;
16              
17 10         30 _initialize();
18              
19 10         17 my $args;
20 10 100       47 if (@_ > 0) {
21 8 50       76 $args = @_ == 1 ? shift : {@_};
22 8 50       62 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       27 if exists $args->{profile};
28             }
29              
30             # every time you load it, we override the version from *your* caller
31 10         26 my $caller = caller;
32 10         42 $arguments_for{$caller} = $args;
33              
34 10         44 my $use_prototypes = _find_option('use_prototypes', $args, $caller, 1);
35 10 100       36 my $exported = ($use_prototypes ? \&p : \&_p_without_prototypes);
36              
37 10         26 my $imported = _find_option('alias', $args, $caller, 'p');
38              
39 8     8   59 { no strict 'refs';
  8         28  
  8         836  
  10         24  
40 10         15 *{"$caller\::$imported"} = $exported;
  10         92  
41 10         21 *{"$caller\::np"} = \&np;
  10         11605  
42             }
43             }
44              
45             sub _initialize {
46             # potential race but worst case is we read it twice :)
47 8     8   59 { no warnings 'redefine'; *_initialize = sub {} }
  8     63   17  
  8         1441  
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   60 no warnings 'redefine';
  8         15  
  8         11647  
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 8974 my (undef, %properties) = @_;
80              
81 13         45 _initialize();
82              
83 13         29 my $caller = caller;
84 13         34 my $args_to_use = _fetch_args_with($caller, \%properties);
85 13 50       34 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       42 if ($printer->colored eq 'auto') {
90 0         0 $printer->{_output_color_level} = 0;
91             }
92              
93 13         44 my $ref = ref $_[0];
94 13 100 100     99 if ($ref eq 'ARRAY' || $ref eq 'HASH' || ($ref eq 'REF' && ref ${$_[0]} eq 'REF')) {
  10   100     46  
      100        
95 3         7 $printer->{_refcount_base}++;
96             }
97 13         45 my $output = $printer->parse($_[0]);
98 13 50       47 if ($printer->caller_message_position eq 'after') {
99 0         0 $output .= $printer->_write_label;
100             }
101             else {
102 13         39 $output = $printer->_write_label . $output;
103             }
104 13         331 return $output;
105             }
106              
107              
108             sub p (\[@$%&];%) {
109 44     44 1 129961 my (undef, %properties) = @_;
110              
111 44         139 _initialize();
112              
113 44         112 my $caller = caller;
114 44         117 my $args_to_use = _fetch_args_with($caller, \%properties);
115 44         168 my $want_value = defined wantarray;
116              
117             # return as quickly as possible under 'quiet'.
118 44 50       210 if ($args_to_use->{quiet}) {
119             # we avoid creating a Data::Printer::Object instance
120             # to speed things up, since we don't do anything under 'quiet'.
121 0         0 my $return_type = Data::Printer::Common::_fetch_anyof(
122             $args_to_use, 'return_value', 'pass', [qw(pass dump void)]
123             );
124 0         0 return _handle_output(undef, undef, $want_value, $_[0], $return_type, 1);
125             }
126              
127 44         261 my $printer = Data::Printer::Object->new($args_to_use);
128              
129 44 0 33     176 if ($printer->colored eq 'auto' && $printer->return_value eq 'dump' && $want_value) {
      33        
130 0         0 $printer->{_output_color_level} = 0;
131             }
132              
133 44         131 my $ref = ref $_[0];
134 44 100 100     285 if ($ref eq 'ARRAY' || $ref eq 'HASH' || ($ref eq 'REF' && ref ${$_[0]} eq 'REF')) {
  17   100     72  
      100        
135 7         16 $printer->{_refcount_base}++;
136             }
137 44         144 my $output = $printer->parse($_[0]);
138 44 100       140 if ($printer->caller_message_position eq 'after') {
139 1         10 $output .= $printer->_write_label;
140             }
141             else {
142 43         130 $output = $printer->_write_label . $output;
143             }
144              
145 44         184 return _handle_output($output, $printer->{output_handle}, $want_value, $_[0], $printer->return_value, undef);
146             }
147              
148             # This is a p() clone without prototypes. Just like regular Data::Dumper,
149             # this version expects a reference as its first argument. We make a single
150             # exception for when we only get one argument, in which case we ref it
151             # for the user and keep going.
152             sub _p_without_prototypes {
153 4     4   94 my (undef, %properties) = @_;
154              
155 4         8 my $item;
156 4 100 66     18 if (!ref $_[0] && @_ == 1) {
157 1         2 my $item_value = $_[0];
158 1         2 $item = \$item_value;
159             }
160              
161 4         14 _initialize();
162              
163 4         8 my $caller = caller;
164 4         13 my $args_to_use = _fetch_args_with($caller, \%properties);
165 4         13 my $want_value = defined wantarray;
166              
167             # return as quickly as possible under 'quiet'.
168 4 50       14 if ($args_to_use->{quiet}) {
169             # we avoid creating a Data::Printer::Object instance
170             # to speed things up, since we don't do anything under 'quiet'.
171 0         0 my $return_type = Data::Printer::Common::_fetch_anyof(
172             $args_to_use, 'return_value', 'pass', [qw(pass dump void)]
173             );
174 0         0 return _handle_output(undef, undef, $want_value, $_[0], $return_type, 1);
175             }
176              
177 4         21 my $printer = Data::Printer::Object->new($args_to_use);
178              
179 4 0 33     12 if ($printer->colored eq 'auto' && $printer->return_value eq 'dump' && $want_value) {
      33        
180 0         0 $printer->{_output_color_level} = 0;
181             }
182              
183 4 100       18 my $ref = ref( defined $item ? $item : $_[0] );
184 4 0 100     22 if ($ref eq 'ARRAY' || $ref eq 'HASH' || ($ref eq 'REF'
    100 33        
      66        
185 0         0 && ref(defined $item ? $item : ${$_[0]}) eq 'REF')) {
186 2         5 $printer->{_refcount_base}++;
187             }
188 4 100       18 my $output = $printer->parse((defined $item ? $item : $_[0]));
189 4 50       12 if ($printer->caller_message_position eq 'after') {
190 0         0 $output .= $printer->_write_label;
191             }
192             else {
193 4         12 $output = $printer->_write_label . $output;
194             }
195              
196 4         12 return _handle_output($output, $printer->{output_handle}, $want_value, $_[0], $printer->return_value, undef);
197             }
198              
199              
200             sub _handle_output {
201 48     48   247 my ($output, $out_handle, $wantarray, $data, $return_type, $quiet) = @_;
202              
203 48 100 100     232 if ($return_type eq 'pass') {
    100          
204 9 50       22 print { $out_handle } $output . "\n" unless $quiet;
  9         436  
205 9         95 require Scalar::Util;
206 9         37 my $ref = Scalar::Util::blessed($data);
207 9 100       52 return $data if defined $ref;
208 8         23 $ref = Scalar::Util::reftype($data);
209 8 50       37 if (!$ref) {
    100          
    100          
    50          
210 0         0 return $data;
211             }
212             elsif ($ref eq 'ARRAY') {
213 2         57 return @$data;
214             }
215             elsif ($ref eq 'HASH') {
216 2         58 return %$data;
217             }
218 12         36 elsif ( grep { $ref eq $_ } qw(REF SCALAR VSTRING) ) {
219 4         108 return $$data;
220             }
221             else {
222 0         0 return $data;
223             }
224             }
225             elsif ($return_type eq 'void' || !$wantarray) {
226 7 50       17 print { $out_handle} $output . "\n" unless $quiet;
  7         297  
227 7         261 return;
228             }
229             else {
230 32         893 return $output;
231             }
232             }
233              
234             sub _fetch_args_with {
235 61     61   141 my ($caller, $run_properties) = @_;
236              
237 61         115 my $args_to_use = {};
238 61 50       206 if (keys %$rc_arguments) {
239             $args_to_use = Data::Printer::Config::_merge_options(
240 61         230 $args_to_use, $rc_arguments->{'_'}
241             );
242 61 50       183 if (exists $rc_arguments->{$caller}) {
243             $args_to_use = Data::Printer::Config::_merge_options(
244 0         0 $args_to_use, $rc_arguments->{$caller}
245             );
246             }
247             }
248 61 50       155 if ($arguments_for{$caller}) {
249             $args_to_use = Data::Printer::Config::_merge_options(
250 61         148 $args_to_use, $arguments_for{$caller}
251             );
252             }
253 61 100       363 if (keys %$run_properties) {
254             $run_properties = Data::Printer::Config::_expand_profile($run_properties)
255 15 50       44 if exists $run_properties->{profile};
256 15         155 $args_to_use = Data::Printer::Config::_merge_options(
257             $args_to_use, $run_properties
258             );
259             }
260 61         142 return $args_to_use;
261             }
262              
263              
264             sub _find_option {
265 20     20   55 my ($key, $args, $caller, $default) = @_;
266              
267 20         39 my $value;
268 20 100 33     104 if (exists $args->{$key}) {
    50          
    50          
269 2         4 $value = $args->{$key};
270             }
271             elsif (
272             exists $rc_arguments->{$caller}
273             && exists $rc_arguments->{$caller}{$key}
274             ) {
275 0         0 $value = $rc_arguments->{$caller}{$key};
276             }
277             elsif (exists $rc_arguments->{'_'}{$key}) {
278 0         0 $value = $rc_arguments->{'_'}{$key};
279             }
280             else {
281 18         30 $value = $default;
282             }
283 20         46 return $value;
284             }
285              
286              
287             'Marielle, presente.';
288             __END__