File Coverage

blib/lib/Data/Dump/Sexp.pm
Criterion Covered Total %
statement 61 61 100.0
branch 20 20 100.0
condition 6 6 100.0
subroutine 12 12 100.0
pod 1 5 20.0
total 100 104 96.1


line stmt bran cond sub pod time code
1             package Data::Dump::Sexp;
2              
3 1     1   56561 use 5.014000;
  1         3  
4 1     1   4 use strict;
  1         2  
  1         15  
5 1     1   4 use warnings;
  1         1  
  1         35  
6 1     1   355 use parent qw/Exporter/;
  1         221  
  1         4  
7              
8             our @EXPORT = qw/dump_sexp/;
9             our @EXPORT_OK = @EXPORT;
10              
11             our $VERSION = '0.002';
12              
13 1     1   81 use Carp qw/croak/;
  1         2  
  1         33  
14 1     1   369 use Data::SExpression;
  1         12732  
  1         5  
15 1     1   42 use Scalar::Util qw/reftype looks_like_number/;
  1         2  
  1         437  
16              
17             sub dump_sexp;
18              
19             sub dump_scalar {
20 22     22 0 30 my ($expr) = @_;
21 22 100       53 if (!defined $expr) {
    100          
22 1         5 "()"
23             } elsif (looks_like_number $expr) {
24 11         36 "$expr"
25             } else {
26 10         12 my $escaped = $expr;
27 10         27 $escaped =~ s,\\,\\\\,g;
28 10         17 $escaped =~ s,",\\",g;
29 10         36 qq,"$escaped",
30             }
31             }
32              
33             sub dump_cons {
34 6     6 0 9 my ($expr) = @_;
35 6         102 my $cdr = $expr->cdr;
36 6         99 my $car = $expr->car;
37 6         38 my $acc = '(' . dump_sexp($car);
38 6         72 while (eval { $cdr->isa('Data::SExpression::Cons') }) {
  10         38  
39 4         57 $car = $cdr->car;
40 4         61 $cdr = $cdr->cdr;
41 4         15 $acc .= ' ' . dump_sexp($car);
42             }
43 6 100       14 if (defined $cdr) {
44 5         8 $acc .= ' . ' . dump_sexp($cdr);
45             }
46 5         55 $acc . ')'
47             }
48              
49             sub dump_array {
50 4     4 0 9 my ($expr) = @_;
51 4         7 '(' . join (' ', map { dump_sexp($_) } @$expr). ')'
  9         71  
52             }
53              
54             sub dump_hash {
55 2     2 0 4 my ($expr) = @_;
56 2         7 my @alist = map { Data::SExpression::cons $_, $expr->{$_} } sort keys %$expr;
  3         25  
57 2         24 dump_array \@alist
58             }
59              
60              
61             sub dump_sexp {
62 47     47 1 4189 my ($expr) = @_;
63 47         91 my $type = reftype $expr;
64 47 100 100     56 if (eval { $expr->can('to_sexp') }) {
  47 100 100     206  
    100          
    100          
    100          
    100          
    100          
65 2         7 dump_sexp $expr->to_sexp
66 45         156 } elsif (eval { $expr->isa('Data::SExpression::Symbol') }) {
67 6         50 "$expr"
68 39         157 } elsif (eval { $expr->isa('Data::SExpression::Cons') }) {
69 6         9 dump_cons $expr
70             } elsif (!defined $type) {
71 22         34 dump_scalar $expr
72             } elsif ($type eq 'ARRAY') {
73 2         7 dump_array $expr
74             } elsif ($type eq 'HASH') {
75 2         4 dump_hash $expr
76             } elsif ($type eq 'SCALAR' || $type eq 'REF' || $type eq 'LVALUE') {
77 6         13 dump_sexp $$expr
78             } else {
79 1         15 croak "Cannot dump value of type $type as sexp"
80             }
81             }
82              
83             1;
84             __END__