File Coverage

blib/lib/Data/Dx.pm
Criterion Covered Total %
statement 78 116 67.2
branch 16 32 50.0
condition 12 26 46.1
subroutine 18 22 81.8
pod n/a
total 124 196 63.2


line stmt bran cond sub pod time code
1             package Data::Dx;
2              
3 3     3   57999 use 5.012;
  3         19  
4 3     3   1482 use utf8;
  3         36  
  3         12  
5 3     3   77 use warnings;
  3         6  
  3         135  
6              
7             our $VERSION = '0.000009';
8              
9 3     3   2429 use Keyword::Declare;
  3         283854  
  3         28  
10              
11             my %COLOUR = (
12             key => 'bold ansi136', # Soft orange
13             value => 'cyan',
14             punct => 'bold ansi245', # Mid-grey
15             comment => 'blue',
16             );
17              
18             my @OUTPUT;
19 3     3   813 BEGIN { @OUTPUT = \*STDERR }
20              
21             sub _dx {
22 28     28   89 my ($expr) = @_;
23 3     3   34 use List::Util 'max';
  3         3  
  3         864  
24              
25             # Flatten the expression to a single line...
26 28         117 $expr =~ s{\s+}{ }g;
27              
28             # Simple arrays and hashes need to be dumped by reference...
29 28 100       166 my $ref = $expr =~ /^[\@%][\w:]++$/ ? q{\\} : q{};
30              
31             # How much to indent...
32 28         137 my $indent = ' ' x (length($expr) + 3);
33              
34             # Handle unbalanced {...} in the expression...
35 28         53 my $str_expr = $expr;
36 28         145 $str_expr =~ s{ ( [\\\{\}] ) }{\\$1}xmsg;
37              
38             # Generate the source...
39 28         269 return qq{Data::Dx::_format_data(__LINE__, __FILE__, q{$str_expr}, q{$indent}, $ref $expr);};
40             }
41              
42              
43             sub import {
44 3     3   39 my (undef, $opt_ref) = @_;
45              
46             # Lexical colour control...
47             $^H{'Data::Dx no_colour'} = 1
48 3 100 66     30 if exists($opt_ref->{colour}) && !$opt_ref->{colour};
49              
50             # Lexical output redirect...
51 3 100       11 if ($opt_ref->{to}) {
52 2         7 $^H{'Data::Dx output'} = @OUTPUT;
53 2         5 push @OUTPUT, $opt_ref->{to};
54             }
55 3         6  
56 3 50 50     48 keyword Dx (Expr $expr) { _dx($expr) }
  3         90  
57 3 50 50     11 keyword Dₓ (Expr $expr) { _dx($expr) }
  3         31  
58 3         12  
59 3         95 utf8->import();
60             }
61 3     14   21  
  14         1164290  
  14         56  
  14         31  
  14         59  
62 3     14   13 sub unimport {
  14     0   986215  
  14         47  
  14         24  
  14         48  
  0         0  
  0         0  
63 3 0 0 3   94547 keyword Dx (Expr $expr) { }
  0         0  
  0         0  
64 3 0 0 3   95307 keyword Dₓ (Expr $expr) { }
  0         0  
  0         0  
65 0         0 }
66              
67 3         18 sub _color {
  0         0  
  0         0  
  0         0  
  0         0  
68 3     0   18 state $colorer = eval {
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
69 0 50   0   0 require Win32::Console::ANSI if $^O eq 'MSWin32';
  0         0  
  0         0  
  0         0  
  2         9  
70 3     3   91862 require Term::ANSIColor;
  2         1238  
71 3     3   91365 sub { return shift if ((caller 1)[10]//{})->{'Data::Dx no_colour'}
72 90 50 50 90   926 || ((caller 2)[10]//{})->{'Data::Dx no_colour'};
      50        
      33        
73 0         0 goto &Term::ANSIColor::colored;
74 3         21 }
  0         0  
  0         0  
  0         0  
75 3   50 0   18 } // sub { shift };
  0     90   0  
  0         0  
  0         0  
  0         0  
  90         118  
  2         15602  
76 90         127 $colorer->(@_);
77             }
78              
79             sub _format_data {
80             # Unpack leadings args...
81 28     28   1798 my $linenum = shift;
82 28         40 my $filename = shift;
83 28         40 my $expr = shift;
84 28         43 my $indent = shift;
85              
86             # Serialize any Contextual::Return::Value objects (which break dump())...
87 28         44 for my $arg (@_) {
88 34 50 100     123 if ((ref($arg)||q{}) =~ m{\A Contextual::Return}xms) {
89 0         0 require Contextual::Return;
90 0         0 Contextual::Return::FREEZE($arg);
91             }
92             }
93              
94             # Then repack data...
95 28 100       66 my $data = @_ > 1 ? [@_] : shift;
96              
97             # Lexical configurations...
98 28   50     103 my $hint = ((caller 0)[10] // {});
99              
100             # Dump the data...
101 28         48 my $dump;
102 28 100       47 if (!defined $data) {
103 6         13 $dump = _color('undef', $COLOUR{value});
104             }
105             else {
106 3     3   2657 use Data::Dump 'dump';
  3         11292  
  3         1065  
107 22         51 $dump = dump($data);
108              
109 22 50       4705 if (!$hint->{'Data::Dx no_colour'}) {
110 0         0 my $bw_dump = $dump;
111 0         0 $dump = q{};
112 0         0 $bw_dump
113             =~ s{ $PPR::GRAMMAR
114             (?: (? (?: (?&PerlString) | (?&PerlBareword) ) (?= \s*+ => ) )
115             | (? (?&PerlLiteral) | sub \s*+ { \s*+ ... \s*+ } )
116             | (? \S )
117             | (? . )
118             )
119             }{
120             $dump .= exists $+{key} ? _color( "$+{key}", $COLOUR{key} )
121             : exists $+{punct} ? _color( "$+{punct}", $COLOUR{punct} )
122             : exists $+{literal} ? _color( "$+{literal}", $COLOUR{value} )
123 0 0       0 : "$+{space}";
    0          
    0          
124 0         0 "";
125             }gxmseo;
126             }
127              
128 22         76 $dump =~ s{ (?! \A ) ^ }{$indent}gxms;
129             }
130              
131 28   50     64 my $output = $OUTPUT[$hint->{'Data::Dx output'} // 0];
132              
133 28         77 print {$output}
134             _color("#line $linenum $filename\n", $COLOUR{comment}),
135             _color($expr, $COLOUR{key}),
136 28         41 _color(' = ', $COLOUR{punct}),
137             "$dump\n\n";
138             }
139              
140              
141              
142              
143             1; # Magic true value required at end of module
144             __END__