File Coverage

recurse2txt
Criterion Covered Total %
statement 55 61 90.1
branch 26 34 76.4
condition 8 9 88.8
subroutine 8 8 100.0
pod n/a
total 97 112 86.6


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             #
3             # recurse2txt routines
4             #
5             # version 1.05, 10-10-11, michael@bizsystems.com
6             #
7             # 10-3-11 updated to bless into calling package
8             # 10-10-11 add SCALAR ref support
9             #
10             #use strict;
11             #use diagnostics;
12 14     14   10953 use overload;
  14         31  
  14         152  
13              
14             # generate a unique signature for a particular hash
15             #
16             # Data::Dumper actually does much more than this, however, it
17             # does not stringify hash's in a consistent manner. i.e. no SORT
18             #
19             # The routine below, while not covering recursion loops, non ascii
20             # characters, etc.... does produce text that can be eval'd and is
21             # consistent with each rendering.
22             #
23             sub Dumper {
24 459 50   459   36495 return "undef\n" unless defined $_[0];
25 459         786 my $ref = ref $_[0];
26 459 50       1087 return "not a reference\n" unless $ref;
27 459 100 100     2477 unless ($ref eq 'HASH' or $ref eq 'ARRAY' or $ref eq 'SCALAR') {
      100        
28 39         241 ($ref) = (overload::StrVal($_[0]) =~ /^(?:.*\=)?([^=]*)\(/);
29             }
30 459         2010 my $p = {
31             depth => 0,
32             elements => 0,
33             };
34 459         4068 (my $pkg = (caller(0))[3]) =~ s/(.+)::Dumper/$1/;
35 459         1666 bless $p,$pkg;
36 459         667 my $data;
37 459 100       1080 if ($ref eq 'HASH') {
    100          
38 49         198 $data = $p->hash_recurse($_[0],"\n");
39             }
40             elsif ($ref eq 'ARRAY') {
41 313         748 $data = $p->array_recurse($_[0]);
42             } else {
43             # return $ref ." unsupported\n";
44 97         245 $data = $p->scalar_recurse($_[0]);
45             }
46 459         3638 $data =~ s/,\n$/;\n/;
47 459         7573 return $p->{elements} ."\t= ". $data;
48             }
49            
50             # input: pointer to scalar, terminator
51             # returns data
52             #
53             sub scalar_recurse {
54 97     97   149 my($p,$ptr,$n) = @_;
55 97 50       372 $n = '' unless $n;
56 97         110 my $data = "\\";
57 97         200 $data .= _dump($p,$$ptr);
58 97         256 $data .= "\n";
59             }
60              
61             # input: pointer to hash, terminator
62             # returns: data
63             #
64             sub hash_recurse {
65 11175     11175   16485 my($p,$ptr,$n) = @_;
66 11175 50       21986 $n = '' unless $n;
67 11175         13895 my $data = "{\n";
68 11175         58944 foreach my $key (sort keys %$ptr) {
69 67289         124855 $data .= "\t'". $key ."'\t=> ";
70 67289         145196 $data .= _dump($p,$ptr->{$key},"\n");
71             }
72 11175         43395 $data .= '},'.$n;
73             }
74              
75             # generate a unique signature for a particular array
76             #
77             # input: pointer to array, terminator
78             # returns: data
79             sub array_recurse {
80 11635     11635   15923 my($p,$ptr,$n) = @_;
81 11635 100       20976 $n = '' unless $n;
82 11635         14156 my $data = '[';
83 11635         19039 foreach my $item (@$ptr) {
84 23012         41165 $data .= _dump($p,$item);
85             }
86 11635         43572 $data .= "],\n";
87             }
88              
89             # input: self, item, append
90             # return: data
91             #
92             sub _dump {
93 90398     90398   152998 my($p,$item,$n) = @_;
94 90398         131269 $p->{elements}++;
95 90398 100       173956 $n = '' unless $n;
96 90398         132003 my $ref = ref $item;
97 90398 100       273507 if ($ref eq 'HASH') {
    100          
    50          
    50          
    50          
    50          
    100          
98 11126         29681 return tabout($p->hash_recurse($item,"\n"));
99             }
100             elsif($ref eq 'ARRAY') {
101 11322         25848 return $p->array_recurse($item,$n);
102             }
103             elsif($ref eq 'SCALAR') {
104             # return q|\$SCALAR,|.$n;
105 0         0 return($p->scalar_recurse($item,$n));
106             }
107 67950         91318 elsif ($ref eq 'GLOB') {
108 0         0 my $g = *{$item};
  0         0  
109 0         0 return "\\$g" .','.$n;
110             }
111 67950         254712 elsif(do {my $g = \$item; ref $g eq 'GLOB'}) {
112 0         0 return "$item" .','.$n;
113             }
114             elsif($ref eq 'CODE') {
115 0         0 return q|sub {'DUMMY'},|.$n;
116             }
117             elsif (defined $item) {
118 67879         121639 return wrap_data($item) .','.$n;
119             }
120             else {
121 71         210 return 'undef,'.$n;
122             }
123             }
124              
125             sub tabout {
126 11126     11126   58077 my @data = split(/\n/,shift);
127 11126         18853 my $data = shift @data;
128 11126         15686 $data .= "\n";
129 11126         19750 foreach(@data) {
130 77921         190466 $data .= "\t$_\n";
131             }
132 11126         59195 $data;
133             }
134              
135             sub wrap_data {
136 67879     67879   87514 my $data = shift;
137 67879 100 66     536960 return ($data =~ /\D/ || $data =~ /^$/)
138             ? q|'|. $data .q|'|
139             : $data;
140             }
141              
142             1;