File Coverage

blib/lib/Data/Dumper/Table.pm
Criterion Covered Total %
statement 83 85 97.6
branch 29 34 85.2
condition 5 5 100.0
subroutine 8 8 100.0
pod 1 1 100.0
total 126 133 94.7


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