File Coverage

blib/lib/Data/Dumper/AutoEncode.pm
Criterion Covered Total %
statement 63 73 86.3
branch 19 28 67.8
condition 10 19 52.6
subroutine 15 15 100.0
pod 1 2 50.0
total 108 137 78.8


line stmt bran cond sub pod time code
1             package Data::Dumper::AutoEncode;
2 2     2   98502 use strict;
  2         5  
  2         50  
3 2     2   10 use warnings;
  2         5  
  2         46  
4 2     2   8 use Carp ();
  2         7  
  2         21  
5 2     2   765 use Encode ();
  2         15716  
  2         46  
6 2     2   14 use Scalar::Util qw(blessed refaddr);
  2         3  
  2         115  
7 2     2   14 use B;
  2         6  
  2         68  
8 2     2   826 use Data::Dumper; # Dumper
  2         9628  
  2         145  
9 2     2   624 use parent qw/Exporter/;
  2         464  
  2         11  
10             our @EXPORT = qw/eDumper Dumper/;
11              
12             our $VERSION = '0.3';
13              
14             our $ENCODING = '';
15             our $CHECK_ALREADY_ENCODED = 0;
16             our $DO_NOT_PROCESS_NUMERIC_VALUE = 1;
17             our $FLAG_STR = '';
18              
19             sub _dump {
20 7     7   23 my $d = Data::Dumper->new(\@_);
21 7         152 return $d->Dump;
22             }
23              
24             sub eDumper {
25 7     7 1 9802 my @args;
26 7         11 for my $arg (@_) {
27 8   100     33 push @args, encode($ENCODING || 'utf8', $arg);
28             }
29 7         14 _dump(@args);
30             }
31              
32             sub encode {
33 8     8 0 15 my ($encoding, $stuff, $check) = @_;
34 8   33     19 $encoding = Encode::find_encoding($encoding)
35             || Carp::croak("unknown encoding '$encoding'");
36 8   50     139 $check ||= 0;
37 8     7   35 _apply(sub { $encoding->encode($_[0], $check) }, {}, $stuff);
  7         31  
38             }
39              
40             # copied from Data::Recursive::Encode
41             sub _apply {
42 10     10   16 my $code = shift;
43 10         13 my $seen = shift;
44              
45 10         11 my @retval;
46 10         16 for my $arg (@_) {
47 12 100       24 if(my $ref = ref $arg){
48 2         6 my $refaddr = refaddr($arg);
49 2         2 my $proto;
50              
51 2 50 0     11 if(defined($proto = $seen->{$refaddr})){
    50          
    50          
    0          
52             # noop
53             }
54             elsif($ref eq 'ARRAY'){
55 0         0 $proto = $seen->{$refaddr} = [];
56 0         0 @{$proto} = _apply($code, $seen, @{$arg});
  0         0  
  0         0  
57             }
58             elsif($ref eq 'HASH'){
59 2         16 $proto = $seen->{$refaddr} = {};
60 2         4 %{$proto} = _apply($code, $seen, %{$arg});
  2         4  
  2         9  
61             }
62             elsif($ref eq 'REF' or $ref eq 'SCALAR'){
63 0         0 $proto = $seen->{$refaddr} = \do{ my $scalar };
  0         0  
64 0         0 ${$proto} = _apply($code, $seen, ${$arg});
  0         0  
  0         0  
65             }
66             else{ # CODE, GLOB, IO, LVALUE etc.
67 0         0 $proto = $seen->{$refaddr} = $arg;
68             }
69              
70 2         5 push @retval, $proto;
71             }
72             else{
73 10 100       18 if (_can_exec($arg)) {
74 7 100       17 push @retval, $FLAG_STR ? $FLAG_STR . $code->($arg) : $code->($arg);
75             }
76             else {
77 3         8 push @retval, $arg;
78             }
79             }
80             }
81              
82 10 50       43 return wantarray ? @retval : $retval[0];
83             }
84              
85             # copied from Data::Recursive::Encode
86             sub _is_number {
87 10     10   12 my $value = shift;
88 10 50       17 return 0 unless defined $value;
89              
90 10         29 my $b_obj = B::svref_2object(\$value);
91 10         30 my $flags = $b_obj->FLAGS;
92 10 100 66     48 return $flags & ( B::SVp_IOK | B::SVp_NOK ) && !( $flags & B::SVp_POK ) ? 1 : 0;
93             }
94              
95             sub _can_exec {
96 10     10   14 my ($arg) = @_;
97              
98 10 50       17 return unless defined($arg);
99 10 100 66     23 return if $DO_NOT_PROCESS_NUMERIC_VALUE && _is_number($arg);
100 9 100       26 return 1 if Encode::is_utf8($arg);
101 3 50 66     10 return 1 if !$CHECK_ALREADY_ENCODED && !Encode::is_utf8($arg);
102              
103 2         4 return;
104             }
105              
106             1;
107              
108             __END__