File Coverage

blib/lib/Data/Dumper/Table.pm
Criterion Covered Total %
statement 86 88 97.7
branch 29 34 85.2
condition 9 9 100.0
subroutine 9 9 100.0
pod 1 1 100.0
total 134 141 95.0


line stmt bran cond sub pod time code
1             package Data::Dumper::Table;
2              
3 2     2   32339 use strict;
  2         4  
  2         87  
4 2     2   11 use warnings;
  2         3  
  2         74  
5 2     2   38 use 5.018;
  2         21  
  2         65  
6 2     2   531 use utf8;
  2         9  
  2         10  
7              
8 2     2   78 use Scalar::Util qw( reftype refaddr blessed );
  2         4  
  2         280  
9 2     2   1329 use Text::Table;
  2         29825  
  2         67  
10              
11 2     2   16 use Exporter qw( import );
  2         2  
  2         1611  
12             our @EXPORT = qw( Tabulate );
13              
14             our $VERSION = '0.012';
15              
16             our %seen;
17              
18             sub Tabulate ($) {
19 1     1 1 23 my ($thing) = @_;
20 1         2 my $run = \do { my $o };
  1         3  
21 1         3 $run = refaddr($run);
22 1         4 $seen{ $run } = { };
23 1         4 my $rv = _tblize($thing, $run);
24 1         6 delete $seen{ $run };
25 1         4 return $rv;
26             }
27              
28             sub _tblize {
29 18     18   27 my ($thing, $run) = @_;
30 18 100       44 return 'undef()' unless defined $thing;
31 17   100     65 my $r = reftype($thing) || '';
32 17   100     91 my $addr = lc sprintf('%x', refaddr($thing) || 0);
33 17         18 my $circular;
34 17 100 100     63 if ($r and defined($seen{ $run }->{ $addr })) {
35 1         2 $circular++;
36             }
37 7         22 my $alias
38             = $r
39 17 100 100     48 ? $r . '(' . ($seen{ $run }->{ $addr } //= scalar keys %{$seen{ $run }}) . ')'
40             : '( scalar )'
41             ;
42 17 100       43 if (my $b = blessed($thing)) {
43 1 50       4 $alias = $b . '=' . $alias unless $b eq 'Regexp';
44             }
45 17 100       26 if ($circular) {
46 1         4 return '-> ' . $alias;
47             }
48 16         99 my $container = Text::Table->new(($alias)x($alias ne '( scalar )'));
49 16         2472 my $inner = $thing;
50 16         17 my $snidge = '+';
51 16 100       63 if ($r eq 'ARRAY') {
    100          
    50          
    100          
    50          
52 3         5 my %header;
53             my @v = grep {
54 3         6 ref($_) eq 'HASH' ?
55 9 100       18 do {
56 4         10 for my $k (keys %$_) {
57 9         14 undef $header{ $k };
58             }
59 4         7 1;
60             } : undef
61             } @$thing;
62 3 100       8 if (@v == @$thing) {
63 1         4 $alias =~ s/ARRAY/ARRAY/;
64 1         4 $container = Text::Table->new($alias);
65 1         237 my @cols = sort keys %header;
66 1 50       2 my @head = map { \' | ', defined($_) ? q{'} . quotemeta($_) . q{'} : 'undef()' } @cols;
  3         10  
67 1         2 shift @head;
68 1         2 unshift @head, \' ';
69 1         3 push @head, \' ';
70 1         10 $inner = Text::Table->new(@head);
71 1         1370 for my $row (@$thing) {
72 2         51 my @body;
73 2         2 for my $k (@cols) {
74 6 100       2606 push @body, (exists($row->{ $k }) ? _tblize($row->{ $k }, $run) : '-');
75             }
76 2         6 $inner->add(@body);
77             }
78             }
79             else {
80 2         6 $inner = Text::Table->new();
81 2         103 my $n = 0;
82 2         8 my $index = "$alias [" . $n++ . "]";
83 2         3 for my $row (@$thing) {
84 7         36 $inner->add($index, _tblize($row, $run));
85 7         9767 $index = (' ' x (2 + length($alias) - length($n))) . '[' . $n++ . ']';
86             }
87 2         22 return $inner;
88             }
89             }
90             elsif ($r eq 'HASH') {
91 3         12 my @keys = sort keys %$thing;
92 3         28 $inner = Text::Table->new();
93 3         162 for my $k (@keys) {
94 5 50       35 $inner->add((defined($k) ? q{'} . quotemeta($k) . q{'} : 'undef()'), '=>', _tblize($thing->{ $k }, $run));
95 5         8381 $snidge = '-';
96             }
97             }
98             elsif ($r eq 'CODE') {
99 0         0 $inner = 'sub DUMMY { }'; # TODO for now
100             }
101             elsif (uc $r eq 'REGEXP') {
102 1         7 return "/$thing/";
103             }
104             elsif ($r) {
105 0         0 $inner = _tblize("\\do { " . $$thing . "}", $run); # TODO for now
106             }
107             else {
108 9         17 $inner = "'" . quotemeta($inner) . "'";
109             }
110 13 100       81 if (ref $inner) {
111 4         10 $container->add($inner->title . $inner->rule('-', $snidge) . $inner->body);
112 4         16258 return $container->title . $container->body;
113             }
114 9         18 $container->add($inner);
115 9         1896 return $container->title . $container->body;
116             }
117              
118             1;
119              
120             __END__