File: Dumper.pm

package info (click to toggle)
libdata-printer-perl 1.002001-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 748 kB
  • sloc: perl: 4,364; makefile: 7; sh: 1
file content (210 lines) | stat: -rw-r--r-- 5,895 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
package Data::Printer::Profile::Dumper;
use strict;
use warnings;

sub profile {
    return {
        show_tainted => 0,
        show_unicode => 0,
        show_lvalue  => 0,
        print_escapes => 0,
        scalar_quotes => q('),
        escape_chars => 'none',
        string_max => 0,
        unicode_charnames => 0,
        array_max => 0,
        index => 0,
        hash_max => 0,
        hash_separator => ' => ',
        align_hash => 0,
        sort_keys => 0,
        quote_keys => 1,
        name => '$VAR1',
        arrows => 'first',
        return_value => 'dump',
        output => 'stderr',
        indent => 10,
        show_readonly => 0,
        show_tied => 0,
        show_dualvar => 'off',
        show_weak => 0,
        show_refcount => 0,
        show_memsize => 0,
        separator => ',',
        end_separator => 0,
        caller_info => 0,
        colored => 0,
        class_method => undef,
        # Data::Printer doesn't provide a way to directly
        # decorate filters, so we do it ourselves:
        filters => [
            {
                '-class'  => \&_data_dumper_class_filter,
                'SCALAR'  => \&_data_dumper_scalar_filter,
                'LVALUE'  => \&_data_dumper_lvalue_filter,
                'HASH'    => \&_data_dumper_hash_filter,
                'ARRAY'   => \&_data_dumper_array_filter,
                'CODE'    => \&_data_dumper_code_filter,
                'FORMAT'  => \&_data_dumper_format_filter,
                'GLOB'    => \&_data_dumper_glob_filter,
                'REF'     => \&_data_dumper_ref_filter,,
                'Regexp'  => \&_data_dumper_regexp_filter,
                'VSTRING' => \&_data_dumper_vstring_filter,
            },
        ],
    };
}

sub _data_dumper_regexp_filter {
    my ($re, $ddp) = @_;
    my $v = "$re";
    my $mod = "";
    if ($v =~ /^\(\?\^?([msixpadlun-]*):([\x00-\xFF]*)\)\z/) {
      $mod = $1;
      $v = $2;
      $mod =~ s/-.*//;
    }
    $v =~ s{/}{\\/}g;
    return _output_wrapper($ddp, $ddp->maybe_colorize("qr/$v/$mod", 'regex'));
}

sub _data_dumper_glob_filter {
    my ($glob, $ddp) = @_;
    my $ret = "$$glob";
    $ret =~ s|\A\*main:|\*:|;
    $ret =~ s|\A\*|\\*{'|;
    $ret .= '\'}';
    return _output_wrapper($ddp, $ddp->maybe_colorize($ret, 'glob'));
}

sub _data_dumper_lvalue_filter {
    my (undef, $ddp) = @_;
    Data::Printer::Common::_warn($ddp, 'cannot handle ref type 10');
    return _output_wrapper($ddp, '');
}

sub _data_dumper_scalar_filter {
    my ($scalar, $ddp) = @_;
    my $ret = Data::Printer::Filter::SCALAR::parse(@_);
    return _output_wrapper($ddp, $ret);
}

sub _data_dumper_ref_filter {
    my ($scalar, $ddp) = @_;
    $ddp->indent;
    my $ret = Data::Printer::Filter::REF::parse(@_);
    $ret =~ s{\A[\\]+\s+}{\\}; # DDP's REF filter adds a space after refs.
    $ddp->outdent;
    return _output_wrapper($ddp, $ret);
}

sub _data_dumper_vstring_filter {
    my ($scalar, $ddp) = @_;
    my $ret = Data::Printer::Filter::VSTRING::parse(@_);
    if ($] < 5.009 && substr($ret, 0, 7) eq 'VSTRING') {
        $ret = $ddp->maybe_colorize('', 'vstring');
    }
    return _output_wrapper($ddp, $ret);
}

sub _data_dumper_format_filter {
    my (undef, $ddp) = @_;
    Data::Printer::Common::_warn($ddp, 'cannot handle ref type 14');
    return _output_wrapper($ddp, '');
}

sub _data_dumper_code_filter {
    my (undef, $ddp) = @_;
    return _output_wrapper($ddp, $ddp->maybe_colorize('sub { "DUMMY" }', 'code'));
}

sub _data_dumper_array_filter {
    my ($hashref, $ddp) = @_;
    my $ret = Data::Printer::Filter::ARRAY::parse(@_);
    return _output_wrapper($ddp, $ret);
}

sub _data_dumper_hash_filter {
    my ($hashref, $ddp) = @_;
    my $ret = Data::Printer::Filter::HASH::parse(@_);
    return _output_wrapper($ddp, $ret);
}

sub _data_dumper_class_filter {
    my ($obj, $ddp) = @_;
    require Scalar::Util;
    my $reftype = Scalar::Util::reftype($obj);
    $reftype = 'Regexp' if $reftype eq 'REGEXP';
    my ($parse_prefix, $parse_suffix) = ('', '');
    if ($reftype eq 'SCALAR' || $reftype eq 'REF' || $reftype eq 'VSTRING') {
        $parse_prefix = 'do{\(my $o = ';
        $parse_prefix .= '\\' if $reftype eq 'REF';
        $parse_suffix = ')}';
    }
    $ddp->indent;
    my $ret = $ddp->maybe_colorize('bless( ' . $parse_prefix, 'method')
            . $ddp->parse_as($reftype, $obj)
            . $ddp->maybe_colorize($parse_suffix, 'method')
            . q|, '| . $ddp->maybe_colorize(ref($obj), 'class') . q|'|
            . $ddp->maybe_colorize(' )', 'method')
            ;
    $ddp->outdent;

    return _output_wrapper($ddp, $ret);
}

sub _output_wrapper {
    my ($ddp, $output) = @_;
    if ($ddp->current_depth == 0) {
        $output = '$VAR1 = ' . $output . ';';
    }
    return $output;
}

1;
__END__


=head1 NAME

Data::Printer::Profile::Dumper - use DDP like Data::Dumper

=head1 SYNOPSIS

While loading Data::Printer:

    use DDP profile => 'Dumper';

While asking for a print:

    p $var, profile => 'Dumper';

or in your C<.dataprinter> file:

    profile = Dumper

=head1 DESCRIPTION

This profile tries to simulate Data::Dumper's output as closely as possible,
using Data::Printer, even skipping types unsupported by Data::Dumper like lvalues
and formats.

It's not guaranteed to be 100% accurate, but hopefully it's close enough :)

=head2 Notable Diferences from Data::Dumper

It's important to notice that this profile tries to emulate
Data::Dumper's I<output>, NOT its behaviour. As such, some things are
still happening in a much DDP-ish way.

* no $VAR2, ...
* return value
* prototypes
* still called 'p' (say alias = 'Dumper' if you want)
* arg is always a reference, so on the top level, references to scalars will be rendered as scalars. References to references and inner references will be rendered properly.


=head1 SEE ALSO

L<Data::Printer>
L<Data::Dumper>