File Coverage

blib/lib/Data/Dx.pm
Criterion Covered Total %
statement 77 116 66.3
branch 16 32 50.0
condition 12 26 46.1
subroutine 18 22 81.8
pod n/a
total 123 196 62.7


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