File Coverage

blib/lib/Data/Show.pm
Criterion Covered Total %
statement 52 54 96.3
branch 7 10 70.0
condition 4 7 57.1
subroutine 9 9 100.0
pod 1 1 100.0
total 73 81 90.1


line stmt bran cond sub pod time code
1             package Data::Show;
2              
3 2     2   14134 use warnings;
  2         2  
  2         53  
4 2     2   7 use strict;
  2         1  
  2         33  
5 2     2   840 use Data::Dump 'dump';
  2         11038  
  2         97  
6 2     2   32 use 5.010;
  2         4  
7              
8             our $VERSION = '0.002004';
9              
10             # Unconditionally export show()...
11             sub import {
12 2     2   6 no strict 'refs';
  2         2  
  2         1996  
13 2     2   15 *{caller().'::show'} = \&show;
  2         40  
14             }
15              
16              
17             # Useful patterns...
18              
19             my $IDENT = qr{
20             [^\W\d]\w* (?: :: [^\W\d]\w* )* | [_\W]
21             }xms;
22              
23 2     2   9 use re 'eval';
  2         3  
  2         316  
24             my $CODE = qr{
25             (?&CODE_FRAGMENT)
26              
27             (?(DEFINE)
28             (?
29             (?: (?"ED)
30             | \b (?: q[qxr]?+ | [msy] | tr ) \s* (?&DELIMITED)
31             | (?&NESTED)
32             | [%\$\@] (?: (?&BRACE_DELIMS) | $IDENT) (?&NESTED)?
33             | [^][{}()"'`;]
34             )++
35             )
36              
37             (?
38             (?: (?"ED)
39             | \b (?: q[qxr]?+ | [msy] | tr ) \s* (?&DELIMITED)
40             | (?&NESTED)
41             | [^][{}()"'`]
42             )++
43             )
44              
45             (?
46             " [^\\"]++ (?: \\. [^\\"]++ )* "
47             | ' [^\\']++ (?: \\. [^\\']++ )* '
48             | ` [^\\`]++ (?: \\. [^\\`]++ )* `
49             | / [^\\/]++ (?: \\. [^\\/]++ )* /
50             | \? [^\\?]++ (?: \\. [^\\?]++ )* \?
51             )
52              
53             (?
54             (?&BRACE_DELIMS)
55             | (?&PAREN_DELIMS)
56             | (?&ANGLE_DELIMS)
57             | (?&SQUARE_DELIMS)
58             | \s++ (?\w) (?:\\.|(?!\g{DELIM_W}).)*+ \g{DELIM_W}
59             | (?[^\w\s]) (?:\\.|(?!\g{DELIM_S}).)*+ \g{DELIM_S}
60             )
61              
62             (?
63             \( (?&NESTED_CODE_FRAGMENT) \)
64             | \[ (?&NESTED_CODE_FRAGMENT) \]
65             | \{ (?&NESTED_CODE_FRAGMENT) \}
66             | \< (?&NESTED_CODE_FRAGMENT) \>
67             )
68              
69             (? \{ (?: [^{}] | \\. | (?&BRACE_DELIMS) )*+ \} )
70             (? \( (?: [^()] | \\. | (?&PAREN_DELIMS) )*+ \) )
71             (? \< (?: [^<>] | \\. | (?&ANGLE_DELIMS) )*+ \> )
72             (? \[ (?: [^][] | \\. | (?&SQUARE_DELIMS) )*+ \] )
73             )
74             }xms;
75              
76              
77             # Configuration for layout of representation...
78             my $DEFAULT_INDENT = 4;
79             my $MAX_WIDTH = 72;
80             my $TITLE_POS = 6;
81              
82             # Be a ninja...
83             our @CARP_NOT;
84              
85             # The whole point of the module...
86             sub show {
87              
88             # Determine context...
89 14     14 1 774 my (undef, $file, $line) = caller();
90              
91             # Extract description of arglist from context...
92 14         10 my ( $desc, $context );
93 14 50       264 if (open my $fh, '<', $file) {
94 14   50     27 for (1..$line-1) { readline($fh) // last }
  297         423  
95 14         11 $desc = do { local $/; readline $fh; };
  14         31  
  14         92  
96             }
97              
98             {
99             # local-ize %+ to avoid clobbering any values with regexes below...
100 2     2   895 local %+;
  2         660  
  2         623  
  14         13  
  14         15  
101              
102             # Trim filename and format context info and description...
103 14         41 $file =~ s{.*[/\\]}{}xms;
104 14         19 $context = "'$file', line $line";
105 14   33     20 $desc //= $context;
106              
107             # Isolate arg list and compress internal whitespace...
108 14         564 $desc =~ s{ \A (?: (?!\bshow) . )*? \b show \b \s* ($CODE) \s* (?: [;\}] .* | \Z ) }{$1}xms;
109 14         35 $desc =~ s{\A \( | \) \Z}{}gxms;
110 14         32 $desc =~ s{\s+}{ }gxms;
111             }
112              
113             # Serialize Contextual::Return::Value objects (which break dump())...
114 14         18 for my $arg (@_) {
115 28 50 100     94 if ((ref($arg)||q{}) =~ m{\A Contextual::Return}xms) {
116 0         0 require Contextual::Return;
117 0         0 Contextual::Return::FREEZE($arg);
118             }
119             }
120              
121             # Serialize argument (restoring it, if it was inappropriately flattened)...
122 14 100       212 my $representation = $desc =~ m{ \A \@ $IDENT \s* \Z }xms ? dump(\@_ )
    100          
123             : $desc =~ m{ \A \% $IDENT \s* \Z }xms ? dump({@_})
124             : dump( @_ );
125              
126             # Indent representation wrt heading...
127 14         1389 $representation =~ s{^}{ q{ } x $DEFAULT_INDENT }gxmse;
  14         33  
128              
129             # Clean up parens around title...
130 14         63 $desc =~ s{ \A \s* (?| \( \s* (.*?) \s* \) | \s* (.*?) \s* ) \Z }
131             {( $1 )}xms;
132              
133             # Insert title into header...
134 14         15 my $header = '=' x $MAX_WIDTH;
135 14         16 substr($header, $TITLE_POS, length($desc), $desc);
136              
137             # Add context if it isn't just context...
138 14 50       26 if ($desc ne "( $context )") {
139 14         14 $context = "[ $context ]";
140 14         16 substr($header, -length($context)-$TITLE_POS, -$TITLE_POS, $context);
141             }
142              
143             # Display data...
144 14         26 print {*STDERR} "$header\n\n$representation\n\n\n";
  14         49  
145              
146 14         125 return;
147             }
148              
149              
150             1; # Magic true value required at end of module
151             __END__