| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Data::Roundtrip; |
|
2
|
|
|
|
|
|
|
|
|
3
|
9
|
|
|
9
|
|
1122912
|
use 5.008; |
|
|
9
|
|
|
|
|
109
|
|
|
4
|
9
|
|
|
9
|
|
49
|
use strict; |
|
|
9
|
|
|
|
|
18
|
|
|
|
9
|
|
|
|
|
193
|
|
|
5
|
9
|
|
|
9
|
|
53
|
use warnings; |
|
|
9
|
|
|
|
|
24
|
|
|
|
9
|
|
|
|
|
469
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.20'; |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
# import params is just one 'no-unicode-escape-permanently' |
|
10
|
|
|
|
|
|
|
# if set, then unicode escaping will not happen at |
|
11
|
|
|
|
|
|
|
# all, even if 'dont-bloody-escape-unicode' is set. |
|
12
|
|
|
|
|
|
|
# Dump's filter and Dumper's qquote overwrite will be permanent |
|
13
|
|
|
|
|
|
|
# which is more efficient but removes the flexibility |
|
14
|
|
|
|
|
|
|
# of having unicode escaped and rendered at will. |
|
15
|
|
|
|
|
|
|
|
|
16
|
9
|
|
|
9
|
|
1738
|
use Encode qw/encode_utf8 decode_utf8/; |
|
|
9
|
|
|
|
|
45882
|
|
|
|
9
|
|
|
|
|
881
|
|
|
17
|
9
|
|
|
9
|
|
6129
|
use JSON qw/decode_json encode_json/; |
|
|
9
|
|
|
|
|
106778
|
|
|
|
9
|
|
|
|
|
53
|
|
|
18
|
9
|
|
|
9
|
|
5373
|
use Unicode::Escape qw/escape unescape/; |
|
|
9
|
|
|
|
|
43243
|
|
|
|
9
|
|
|
|
|
585
|
|
|
19
|
9
|
|
|
9
|
|
4027
|
use YAML; |
|
|
9
|
|
|
|
|
63432
|
|
|
|
9
|
|
|
|
|
516
|
|
|
20
|
9
|
|
|
9
|
|
5796
|
use Data::Dumper qw/Dumper/; |
|
|
9
|
|
|
|
|
57394
|
|
|
|
9
|
|
|
|
|
609
|
|
|
21
|
9
|
|
|
9
|
|
3070
|
use Data::Dump qw/pp/; |
|
|
9
|
|
|
|
|
32120
|
|
|
|
9
|
|
|
|
|
556
|
|
|
22
|
9
|
|
|
9
|
|
4210
|
use Data::Dump::Filtered; |
|
|
9
|
|
|
|
|
3297
|
|
|
|
9
|
|
|
|
|
442
|
|
|
23
|
|
|
|
|
|
|
|
|
24
|
9
|
|
|
9
|
|
60
|
use Exporter; # we have our own import() don't import it |
|
|
9
|
|
|
|
|
21
|
|
|
|
9
|
|
|
|
|
2535
|
|
|
25
|
|
|
|
|
|
|
# the EXPORT_OK and EXPORT_TAGS is code by [kcott] @ Perlmongs.org, thanks! |
|
26
|
|
|
|
|
|
|
# see https://perlmonks.org/?node_id=11115288 |
|
27
|
|
|
|
|
|
|
our (@EXPORT_OK, %EXPORT_TAGS); |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
my $_permanent_override = 0; |
|
30
|
|
|
|
|
|
|
my $_permanent_filter = 0; |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# THESE are taken verbatim from Data::Dumper (Data/Dumper.pm) |
|
33
|
|
|
|
|
|
|
# they are required for _qquote_redefinition_by_Corion() |
|
34
|
|
|
|
|
|
|
# which needed to access them as, e.g. %Data::Dumper::esc |
|
35
|
|
|
|
|
|
|
# because they are private vars, they are not coming out! |
|
36
|
|
|
|
|
|
|
# and so here they are: |
|
37
|
|
|
|
|
|
|
my $Data_Dumper_IS_ASCII = ord 'A' == 65; |
|
38
|
|
|
|
|
|
|
my %Data_Dumper_esc = ( |
|
39
|
|
|
|
|
|
|
"\a" => "\\a", |
|
40
|
|
|
|
|
|
|
"\b" => "\\b", |
|
41
|
|
|
|
|
|
|
"\t" => "\\t", |
|
42
|
|
|
|
|
|
|
"\n" => "\\n", |
|
43
|
|
|
|
|
|
|
"\f" => "\\f", |
|
44
|
|
|
|
|
|
|
"\r" => "\\r", |
|
45
|
|
|
|
|
|
|
"\e" => "\\e", |
|
46
|
|
|
|
|
|
|
); |
|
47
|
|
|
|
|
|
|
my $Data_Dumper_low_controls = ($Data_Dumper_IS_ASCII) |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# This includes \177, because traditionally it has been |
|
50
|
|
|
|
|
|
|
# output as octal, even though it isn't really a "low" |
|
51
|
|
|
|
|
|
|
# control |
|
52
|
|
|
|
|
|
|
? qr/[\0-\x1f\177]/ |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# EBCDIC low controls. |
|
55
|
|
|
|
|
|
|
: qr/[\0-\x3f]/; |
|
56
|
|
|
|
|
|
|
# END verbatim from Data::Dumper (Data/Dumper.pm) |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
BEGIN { |
|
59
|
9
|
|
|
9
|
|
51
|
my @file = qw{read_from_file write_to_file}; |
|
60
|
9
|
|
|
|
|
30
|
my @fh = qw{read_from_filehandle write_to_filehandle}; |
|
61
|
9
|
|
|
|
|
26
|
my @io = (@file, @fh); |
|
62
|
9
|
|
|
|
|
37
|
my @json = qw{perl2json json2perl json2dump json2yaml json2json jsonfile2perl}; |
|
63
|
9
|
|
|
|
|
58
|
my @yaml = qw{perl2yaml yaml2perl yaml2json yaml2dump yaml2yaml yamlfile2perl}; |
|
64
|
9
|
|
|
|
|
41
|
my @dump = qw{perl2dump perl2dump_filtered perl2dump_homebrew |
|
65
|
|
|
|
|
|
|
dump2perl dump2json dump2yaml dump2dump}; |
|
66
|
9
|
|
|
|
|
59
|
my @all = (@io, @json, @yaml, @dump); |
|
67
|
9
|
|
|
|
|
57
|
@EXPORT_OK = @all; |
|
68
|
9
|
|
|
|
|
1283
|
%EXPORT_TAGS = ( |
|
69
|
|
|
|
|
|
|
file => [@file], |
|
70
|
|
|
|
|
|
|
fh => [@fh], |
|
71
|
|
|
|
|
|
|
io => [@io], |
|
72
|
|
|
|
|
|
|
json => [@json], |
|
73
|
|
|
|
|
|
|
yaml => [@yaml], |
|
74
|
|
|
|
|
|
|
dump => [@dump], |
|
75
|
|
|
|
|
|
|
all => [@all], |
|
76
|
|
|
|
|
|
|
); |
|
77
|
|
|
|
|
|
|
} # end BEGIN |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub DESTROY { |
|
80
|
0
|
0
|
|
0
|
|
0
|
Data::Dump::Filtered::remove_dump_filter( \& DataDumpFilterino ) |
|
81
|
|
|
|
|
|
|
if $_permanent_filter; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub import { |
|
85
|
|
|
|
|
|
|
# what comes here is (package, param1, param2...) = @_ |
|
86
|
|
|
|
|
|
|
# for something like |
|
87
|
|
|
|
|
|
|
# use Data::Roundtrip qw/param1 params2 .../; |
|
88
|
|
|
|
|
|
|
# we are looking for a param, eq to 'no-unicode-escape-permanently' |
|
89
|
|
|
|
|
|
|
# or 'unicode-escape-permanently' |
|
90
|
|
|
|
|
|
|
# the rest we must pass to the Exporter::import() but in a tricky way |
|
91
|
|
|
|
|
|
|
# so as it injects all these subs in the proper namespace. |
|
92
|
|
|
|
|
|
|
# that call is at the end, but with our parameter removed from the list |
|
93
|
10
|
|
|
10
|
|
145
|
for(my $i=@_;$i-->1;){ |
|
94
|
6
|
100
|
|
|
|
39
|
if( $_[$i] eq 'no-unicode-escape-permanently' ){ |
|
|
|
100
|
|
|
|
|
|
|
95
|
1
|
|
|
|
|
3
|
splice @_, $i, 1; # remove it from the list |
|
96
|
1
|
|
|
|
|
2
|
$Data::Dumper::Useperl = 1; |
|
97
|
1
|
|
|
|
|
2
|
$Data::Dumper::Useqq='utf8'; |
|
98
|
9
|
|
|
9
|
|
71
|
no warnings 'redefine'; |
|
|
9
|
|
|
|
|
20
|
|
|
|
9
|
|
|
|
|
21288
|
|
|
99
|
1
|
|
|
|
|
4
|
*Data::Dumper::qquote = \& _qquote_redefinition_by_Corion; |
|
100
|
1
|
|
|
|
|
2
|
$_permanent_override = 1; |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# add a filter to Data::Dump |
|
103
|
1
|
|
|
|
|
4
|
Data::Dump::Filtered::add_dump_filter( \& DataDumpFilterino ); |
|
104
|
1
|
|
|
|
|
10
|
$_permanent_filter = 1; |
|
105
|
|
|
|
|
|
|
} elsif( $_[$i] eq 'unicode-escape-permanently' ){ |
|
106
|
1
|
|
|
|
|
3
|
splice @_, $i, 1; # remove it from the list |
|
107
|
|
|
|
|
|
|
# this is the case which we want to escape unicode permanently |
|
108
|
|
|
|
|
|
|
# which is the default behaviour for Dump and Dumper |
|
109
|
1
|
|
|
|
|
3
|
$_permanent_override = 2; |
|
110
|
1
|
|
|
|
|
2
|
$_permanent_filter = 2; |
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
# now let Exporter handle the rest of the params if any |
|
114
|
|
|
|
|
|
|
# from ikegami at https://www.perlmonks.org/?node_id=1214104 |
|
115
|
10
|
|
|
|
|
16995
|
goto &Exporter::import; |
|
116
|
|
|
|
|
|
|
} |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub perl2json { |
|
119
|
25
|
|
|
25
|
1
|
109083
|
my $pv = $_[0]; |
|
120
|
25
|
100
|
|
|
|
80
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
121
|
|
|
|
|
|
|
my $pretty_printing = exists($params->{'pretty'}) && defined($params->{'pretty'}) |
|
122
|
25
|
100
|
66
|
|
|
144
|
? $params->{'pretty'} : 0 |
|
123
|
|
|
|
|
|
|
; |
|
124
|
|
|
|
|
|
|
my $escape_unicode = exists($params->{'escape-unicode'}) && defined($params->{'escape-unicode'}) |
|
125
|
25
|
100
|
66
|
|
|
107
|
? $params->{'escape-unicode'} : 0 |
|
126
|
|
|
|
|
|
|
; |
|
127
|
25
|
|
|
|
|
76
|
my $json_string; |
|
128
|
25
|
100
|
|
|
|
69
|
if( $escape_unicode ){ |
|
129
|
8
|
100
|
|
|
|
24
|
if( $pretty_printing ){ |
|
130
|
2
|
|
|
|
|
153
|
$json_string = JSON->new->utf8(1)->pretty->encode($pv); |
|
131
|
6
|
|
|
|
|
64
|
} else { $json_string = JSON->new->utf8(1)->encode($pv) } |
|
132
|
8
|
100
|
|
|
|
52
|
if ( _has_utf8($json_string) ){ |
|
133
|
7
|
|
|
|
|
33
|
$json_string = Unicode::Escape::escape($json_string, 'utf8'); |
|
134
|
|
|
|
|
|
|
} |
|
135
|
|
|
|
|
|
|
} else { |
|
136
|
17
|
50
|
|
|
|
39
|
if( $pretty_printing ){ |
|
137
|
0
|
|
|
|
|
0
|
$json_string = JSON->new->utf8(0)->pretty->encode($pv); |
|
138
|
|
|
|
|
|
|
} else { |
|
139
|
|
|
|
|
|
|
# cpan testers report: |
|
140
|
|
|
|
|
|
|
# https://www.cpantesters.org/cpan/report/1fba88ee-6bfa-1014-8b5d-8080f52666f1 |
|
141
|
|
|
|
|
|
|
# cannot encode reference to scalar at C:\strawberry163\cpan\build\Data-Roundtrip-0.11-0\blib\lib/Data/Roundtrip.pm line 138. |
|
142
|
|
|
|
|
|
|
# following is line 138: |
|
143
|
17
|
|
|
|
|
477
|
$json_string = JSON->new->utf8(0)->encode($pv); |
|
144
|
|
|
|
|
|
|
} |
|
145
|
|
|
|
|
|
|
} |
|
146
|
25
|
50
|
|
|
|
25846
|
if( ! $json_string ){ warn "perl2json() : error, no json produced from perl variable"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
147
|
25
|
|
|
|
|
95
|
return $json_string |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
sub perl2yaml { |
|
150
|
23
|
|
|
23
|
1
|
6852
|
my $pv = $_[0]; |
|
151
|
23
|
100
|
|
|
|
67
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
152
|
|
|
|
|
|
|
my $pretty_printing = exists($params->{'pretty'}) && defined($params->{'pretty'}) |
|
153
|
23
|
100
|
66
|
|
|
96
|
? $params->{'pretty'} : 0 |
|
154
|
|
|
|
|
|
|
; |
|
155
|
23
|
100
|
50
|
|
|
175
|
warn "perl2yaml() : pretty-printing is not supported for YAML output" and $pretty_printing=0 |
|
156
|
|
|
|
|
|
|
if $pretty_printing; |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
my $escape_unicode = exists($params->{'escape-unicode'}) && defined($params->{'escape-unicode'}) |
|
159
|
23
|
100
|
66
|
|
|
107
|
? $params->{'escape-unicode'} : 0 |
|
160
|
|
|
|
|
|
|
; |
|
161
|
23
|
|
|
|
|
42
|
my ($yaml_string, $escaped); |
|
162
|
23
|
100
|
|
|
|
61
|
if( $escape_unicode ){ |
|
163
|
|
|
|
|
|
|
#if( $pretty_printing ){ |
|
164
|
|
|
|
|
|
|
# it's here just for historic purposes, this is not supported and a warning is issued |
|
165
|
|
|
|
|
|
|
#$yaml_string = eval { YAML::Dump($pv) }; |
|
166
|
|
|
|
|
|
|
#if( $@ ){ warn "error, call to ".'YAML::Dump()'." has failed with this exception:\n".$@; return undef } |
|
167
|
|
|
|
|
|
|
# this does not work :( no pretty printing for yaml |
|
168
|
|
|
|
|
|
|
#$yaml_string = Data::Format::Pretty::YAML::format_pretty($pv); |
|
169
|
|
|
|
|
|
|
#} else { |
|
170
|
|
|
|
|
|
|
# intercepting a die by wrapping in an eval |
|
171
|
7
|
|
|
|
|
13
|
$yaml_string = eval { YAML::Dump($pv) }; |
|
|
7
|
|
|
|
|
27
|
|
|
172
|
7
|
0
|
33
|
|
|
25368
|
if( $@ || ! defined($yaml_string) ){ warn "error, call to ".'YAML::Dump()'." has failed".(defined($@)?" with this exception:\n".$@:"")."."; return undef } |
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
173
|
|
|
|
|
|
|
#} |
|
174
|
7
|
50
|
|
|
|
21
|
if( ! $yaml_string ){ warn "perl2yaml() : error, no yaml produced from perl variable"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
175
|
7
|
100
|
|
|
|
26
|
if( _has_utf8($yaml_string) ){ |
|
176
|
6
|
|
|
|
|
51
|
utf8::encode($yaml_string); |
|
177
|
6
|
|
|
|
|
22
|
$yaml_string = Unicode::Escape::escape($yaml_string, 'utf8'); |
|
178
|
|
|
|
|
|
|
} |
|
179
|
|
|
|
|
|
|
} else { |
|
180
|
|
|
|
|
|
|
#if( $pretty_printing ){ |
|
181
|
|
|
|
|
|
|
# it's here just for historic purposes, this is not supported and a warning is issued |
|
182
|
|
|
|
|
|
|
#$yaml_string = Data::Format::Pretty::YAML::format_pretty($pv); |
|
183
|
|
|
|
|
|
|
#} else { |
|
184
|
16
|
|
|
|
|
63
|
$yaml_string = YAML::Dump($pv); |
|
185
|
16
|
0
|
33
|
|
|
187151
|
if( $@ || ! defined($yaml_string) ){ warn "error, call to ".'YAML::Dump()'." has failed".(defined($@)?" with this exception:\n".$@:"")."."; return undef } |
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
186
|
|
|
|
|
|
|
#} |
|
187
|
16
|
50
|
|
|
|
61
|
if( ! $yaml_string ){ warn "perl2yaml() : error, no yaml produced from perl variable"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
188
|
|
|
|
|
|
|
} |
|
189
|
23
|
|
|
|
|
20124
|
return $yaml_string |
|
190
|
|
|
|
|
|
|
} |
|
191
|
|
|
|
|
|
|
sub yaml2perl { |
|
192
|
23
|
|
|
23
|
1
|
3657
|
my $yaml_string = $_[0]; |
|
193
|
|
|
|
|
|
|
#my $params = defined($_[1]) ? $_[1] : {}; |
|
194
|
|
|
|
|
|
|
# intercepting a die by wrapping in an eval |
|
195
|
23
|
|
|
|
|
54
|
my $pv = eval { YAML::Load($yaml_string) }; |
|
|
23
|
|
|
|
|
84
|
|
|
196
|
23
|
0
|
33
|
|
|
319010
|
if( $@ || ! defined($pv) ){ warn "yaml2perl() : error, call to YAML::Load() has failed".(defined($@)?" with this exception:\n".$@:"")."."; return undef } |
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
197
|
23
|
|
|
|
|
76
|
return $pv |
|
198
|
|
|
|
|
|
|
} |
|
199
|
|
|
|
|
|
|
sub yamlfile2perl { |
|
200
|
4
|
|
|
4
|
1
|
13015
|
my $yaml_file = $_[0]; |
|
201
|
|
|
|
|
|
|
#my $params = defined($_[1]) ? $_[1] : {}; |
|
202
|
4
|
|
|
|
|
14
|
my $contents = read_from_file($yaml_file); |
|
203
|
4
|
50
|
|
|
|
21
|
if( ! defined $contents ){ warn "yamlfile2perl() : error, failed to read from file '${yaml_file}'."; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
204
|
4
|
|
|
|
|
13
|
my $pv = yaml2perl($contents); |
|
205
|
4
|
50
|
|
|
|
17
|
if( ! defined $pv ){ warn "yamlfile2perl() : error, call to yaml2perl() has failed after reading yaml string from file '${yaml_file}'."; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
206
|
4
|
|
|
|
|
17
|
return $pv; |
|
207
|
|
|
|
|
|
|
} |
|
208
|
|
|
|
|
|
|
sub json2perl { |
|
209
|
27
|
|
|
27
|
1
|
3378
|
my $json_string = $_[0]; |
|
210
|
|
|
|
|
|
|
#my $params = defined($_[1]) ? $_[1] : {}; |
|
211
|
27
|
|
|
|
|
51
|
my $pv; |
|
212
|
27
|
100
|
|
|
|
75
|
if( _has_utf8($json_string) ){ |
|
213
|
|
|
|
|
|
|
# intercepting a die by wrapping in an eval |
|
214
|
17
|
|
|
|
|
42
|
$pv = eval { JSON::decode_json(Encode::encode_utf8($json_string)) }; |
|
|
17
|
|
|
|
|
416
|
|
|
215
|
17
|
0
|
33
|
|
|
131
|
if( $@ || ! defined($pv) ){ warn "json2perl() : error, call to json2perl() has failed".(defined($@)?" with this exception: $@":""); return undef } |
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
216
|
|
|
|
|
|
|
} else { |
|
217
|
|
|
|
|
|
|
# intercepting a die by wrapping in an eval |
|
218
|
10
|
|
|
|
|
25
|
$pv = eval { JSON::decode_json($json_string) }; |
|
|
10
|
|
|
|
|
177
|
|
|
219
|
10
|
0
|
33
|
|
|
70
|
if( $@ || ! defined($pv) ){ warn "json2perl() : error, call to json2perl() has failed".(defined($@)?" with this exception: $@":""); return undef } |
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
220
|
|
|
|
|
|
|
} |
|
221
|
27
|
|
|
|
|
68
|
return $pv; |
|
222
|
|
|
|
|
|
|
} |
|
223
|
|
|
|
|
|
|
sub jsonfile2perl { |
|
224
|
4
|
|
|
4
|
1
|
5190
|
my $json_file = $_[0]; |
|
225
|
|
|
|
|
|
|
#my $params = defined($_[1]) ? $_[1] : {}; |
|
226
|
4
|
|
|
|
|
15
|
my $contents = read_from_file($json_file); |
|
227
|
4
|
50
|
|
|
|
22
|
if( ! defined $contents ){ warn "jsonfile2perl() : error, failed to read from file '${json_file}'."; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
228
|
4
|
|
|
|
|
15
|
my $pv = json2perl($contents); |
|
229
|
4
|
50
|
|
|
|
14
|
if( ! defined $pv ){ warn "jsonfile2perl() : error, call to json2perl() has failed after reading json string from file '${json_file}'."; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
230
|
4
|
|
|
|
|
12
|
return $pv; |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
sub json2json { |
|
233
|
0
|
|
|
0
|
1
|
0
|
my $json_string = $_[0]; |
|
234
|
0
|
0
|
|
|
|
0
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
235
|
|
|
|
|
|
|
|
|
236
|
0
|
|
|
|
|
0
|
my $pv = json2perl($json_string, $params); |
|
237
|
0
|
0
|
|
|
|
0
|
if( ! defined $pv ){ warn "json2perl() : error, call to json2perl() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
238
|
0
|
|
|
|
|
0
|
$json_string = perl2json($pv, $params); |
|
239
|
0
|
0
|
|
|
|
0
|
if( ! defined $json_string ){ warn "json2perl() : error, call to perl2json() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
240
|
|
|
|
|
|
|
|
|
241
|
0
|
|
|
|
|
0
|
return $json_string; |
|
242
|
|
|
|
|
|
|
} |
|
243
|
|
|
|
|
|
|
sub yaml2yaml { |
|
244
|
0
|
|
|
0
|
1
|
0
|
my $yaml_string = $_[0]; |
|
245
|
0
|
0
|
|
|
|
0
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
246
|
|
|
|
|
|
|
|
|
247
|
0
|
|
|
|
|
0
|
my $pv = yaml2perl($yaml_string, $params); |
|
248
|
0
|
0
|
|
|
|
0
|
if( ! defined $pv ){ warn "yaml2perl() : error, call to yaml2perl() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
249
|
0
|
|
|
|
|
0
|
$yaml_string = perl2yaml($pv, $params); |
|
250
|
0
|
0
|
|
|
|
0
|
if( ! defined $yaml_string ){ warn "yaml2perl() : error, call to perl2yaml() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
251
|
|
|
|
|
|
|
|
|
252
|
0
|
|
|
|
|
0
|
return $yaml_string; |
|
253
|
|
|
|
|
|
|
} |
|
254
|
|
|
|
|
|
|
sub dump2dump { |
|
255
|
0
|
|
|
0
|
0
|
0
|
my $dump_string = $_[0]; |
|
256
|
0
|
0
|
|
|
|
0
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
257
|
|
|
|
|
|
|
|
|
258
|
0
|
|
|
|
|
0
|
my $pv = dump2perl($dump_string, $params); |
|
259
|
0
|
0
|
|
|
|
0
|
if( ! defined $pv ){ warn "dump2perl() : error, call to dump2perl() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
260
|
0
|
|
|
|
|
0
|
$dump_string = perl2dump($pv, $params); |
|
261
|
0
|
0
|
|
|
|
0
|
if( ! defined $dump_string ){ warn "dump2perl() : error, call to perl2dump() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
262
|
|
|
|
|
|
|
|
|
263
|
0
|
|
|
|
|
0
|
return $dump_string; |
|
264
|
|
|
|
|
|
|
} |
|
265
|
|
|
|
|
|
|
sub yaml2json { |
|
266
|
12
|
|
|
12
|
1
|
4038
|
my $yaml_string = $_[0]; |
|
267
|
12
|
100
|
|
|
|
37
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
# is it escaped already? |
|
270
|
12
|
|
|
|
|
74
|
$yaml_string =~ s/\\u([0-9a-fA-F]{4})/eval "\"\\x{$1}\""/ge; |
|
|
408
|
|
|
|
|
15659
|
|
|
271
|
12
|
|
|
|
|
76
|
my $pv = yaml2perl($yaml_string, $params); |
|
272
|
12
|
50
|
|
|
|
35
|
if( ! $pv ){ warn "yaml2json() : error, call to yaml2perl() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
273
|
12
|
|
|
|
|
29
|
my $json = perl2json($pv, $params); |
|
274
|
12
|
50
|
|
|
|
27
|
if( ! $json ){ warn "yaml2json() : error, call to perl2json() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
275
|
12
|
|
|
|
|
76
|
return $json |
|
276
|
|
|
|
|
|
|
} |
|
277
|
|
|
|
|
|
|
sub yaml2dump { |
|
278
|
0
|
|
|
0
|
1
|
0
|
my $yaml_string = $_[0]; |
|
279
|
0
|
0
|
|
|
|
0
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
280
|
|
|
|
|
|
|
|
|
281
|
0
|
|
|
|
|
0
|
my $pv = yaml2perl($yaml_string, $params); |
|
282
|
0
|
0
|
|
|
|
0
|
if( ! $pv ){ warn "yaml2json() : error, call to yaml2perl() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
283
|
0
|
|
|
|
|
0
|
my $dump = perl2dump($pv, $params); |
|
284
|
0
|
0
|
|
|
|
0
|
if( ! $dump ){ warn "yaml2dump() : error, call to perl2dump() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
285
|
0
|
|
|
|
|
0
|
return $dump |
|
286
|
|
|
|
|
|
|
} |
|
287
|
|
|
|
|
|
|
sub json2dump { |
|
288
|
4
|
|
|
4
|
1
|
1188
|
my $json_string = $_[0]; |
|
289
|
4
|
50
|
|
|
|
13
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
290
|
|
|
|
|
|
|
|
|
291
|
4
|
|
|
|
|
11
|
my $pv = json2perl($json_string, $params); |
|
292
|
4
|
50
|
|
|
|
12
|
if( ! $pv ){ warn "json2json() : error, call to json2perl() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
293
|
4
|
|
|
|
|
14
|
my $dump = perl2dump($pv, $params); |
|
294
|
4
|
50
|
|
|
|
303
|
if( ! $dump ){ warn "json2dump() : error, call to perl2dump() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
295
|
4
|
|
|
|
|
18
|
return $dump |
|
296
|
|
|
|
|
|
|
} |
|
297
|
|
|
|
|
|
|
sub dump2json { |
|
298
|
2
|
|
|
2
|
1
|
339
|
my $dump_string = $_[0]; |
|
299
|
2
|
50
|
|
|
|
6
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
300
|
|
|
|
|
|
|
|
|
301
|
2
|
|
|
|
|
10
|
my $pv = dump2perl($dump_string, $params); |
|
302
|
2
|
50
|
|
|
|
5
|
if( ! $pv ){ warn "dump2json() : error, call to dump2perl() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
303
|
2
|
|
|
|
|
14
|
my $json_string = perl2json($pv, $params); |
|
304
|
2
|
50
|
|
|
|
12
|
if( ! $json_string ){ warn "dump2json() : error, call to perl2json() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
305
|
2
|
|
|
|
|
37
|
return $json_string |
|
306
|
|
|
|
|
|
|
} |
|
307
|
|
|
|
|
|
|
sub dump2yaml { |
|
308
|
0
|
|
|
0
|
1
|
0
|
my $dump_string = $_[0]; |
|
309
|
0
|
0
|
|
|
|
0
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
310
|
|
|
|
|
|
|
|
|
311
|
0
|
|
|
|
|
0
|
my $pv = dump2perl($dump_string, $params); |
|
312
|
0
|
0
|
|
|
|
0
|
if( ! $pv ){ warn "yaml2yaml() : error, call to yaml2perl() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
313
|
0
|
|
|
|
|
0
|
my $yaml_string = perl2yaml($pv, $params); |
|
314
|
0
|
0
|
|
|
|
0
|
if( ! $yaml_string ){ warn "dump2yaml() : error, call to perl2yaml() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
315
|
0
|
|
|
|
|
0
|
return $yaml_string |
|
316
|
|
|
|
|
|
|
} |
|
317
|
|
|
|
|
|
|
sub json2yaml { |
|
318
|
12
|
|
|
12
|
1
|
2935
|
my $json_string = $_[0]; |
|
319
|
12
|
100
|
|
|
|
37
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
320
|
|
|
|
|
|
|
|
|
321
|
12
|
|
|
|
|
32
|
my $pv = json2perl($json_string, $params); |
|
322
|
12
|
50
|
|
|
|
30
|
if( ! defined $pv ){ warn "json2yaml() : error, call to json2perl() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
323
|
12
|
|
|
|
|
28
|
my $yaml_string = perl2yaml($pv, $params); |
|
324
|
12
|
50
|
|
|
|
35
|
if( ! defined $yaml_string ){ warn "json2yaml() : error, call to perl2yaml() has failed"; return undef } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
325
|
12
|
|
|
|
|
54
|
return $yaml_string |
|
326
|
|
|
|
|
|
|
} |
|
327
|
|
|
|
|
|
|
sub dump2perl { |
|
328
|
|
|
|
|
|
|
# WARNING: we eval() input string with alleged |
|
329
|
|
|
|
|
|
|
# output from Data::Dump. Are you sure you trust |
|
330
|
|
|
|
|
|
|
# the input string ($dump_string) for an eval() ? |
|
331
|
|
|
|
|
|
|
# WARNING-2: I am considering removing this sub in future releases because of the eval() |
|
332
|
35
|
|
|
35
|
1
|
89057
|
my $dump_string = $_[0]; |
|
333
|
|
|
|
|
|
|
#my $params = defined($_[1]) ? $_[1] : {}; |
|
334
|
|
|
|
|
|
|
|
|
335
|
35
|
|
|
|
|
212
|
$dump_string =~ s/^\$VAR1\s*=\s*//g; |
|
336
|
35
|
|
|
|
|
1455
|
warn "dump2perl() : WARNING, eval()'ing input string, are you sure you did check its content ?\n"; |
|
337
|
35
|
|
|
|
|
805
|
warn "dump2perl() : WARNING, this sub will be removed in future releases.\n"; |
|
338
|
|
|
|
|
|
|
# WARNING: eval() of unknown input: |
|
339
|
35
|
|
|
|
|
4025
|
my $pv = eval($dump_string); |
|
340
|
35
|
0
|
33
|
|
|
293
|
if( $@ || ! defined($pv) ){ warn "input string:${pv}\nend input string.\ndump2perl() : error, eval() of input string (alledgedly a perl variable, see above) has failed".(defined($@)?" with this exception:\n".$@:"")."."; return undef } |
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
341
|
35
|
|
|
|
|
118
|
return $pv |
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
# this bypasses Data::Dumper's obsession with escaping |
|
344
|
|
|
|
|
|
|
# non-ascii characters by redefining the qquote() sub |
|
345
|
|
|
|
|
|
|
# The redefinition code is by [Corion] @ Perlmonks and cpan |
|
346
|
|
|
|
|
|
|
# see https://perlmonks.org/?node_id=11115271 |
|
347
|
|
|
|
|
|
|
# So, it still uses Data::Dumper to dump the input perl var |
|
348
|
|
|
|
|
|
|
# but with its qquote() sub redefined. See section CAVEATS |
|
349
|
|
|
|
|
|
|
# for a wee problem that may appear in the future. |
|
350
|
|
|
|
|
|
|
# The default behaviour is NOT to escape unicode |
|
351
|
|
|
|
|
|
|
# (which is the opposite of what Data::Dumper is doing) |
|
352
|
|
|
|
|
|
|
# see options, below, on how to change this. |
|
353
|
|
|
|
|
|
|
# input is the perl variable (as a reference, e.g. scalar, hashref, arrayref) |
|
354
|
|
|
|
|
|
|
# followed by optional hashref of options which can be |
|
355
|
|
|
|
|
|
|
# terse |
|
356
|
|
|
|
|
|
|
# indent |
|
357
|
|
|
|
|
|
|
# dont-bloody-escape-unicode, |
|
358
|
|
|
|
|
|
|
# escape-unicode, |
|
359
|
|
|
|
|
|
|
# The last 2 control how unicode is printed, either escaped, |
|
360
|
|
|
|
|
|
|
# like \x{3b1} or 'a' <<< which is unicoded greek alpha but did not want to pollute with unicode this file |
|
361
|
|
|
|
|
|
|
# the former behaviour can be with dont-bloody-escape-unicode=>0 or escape-unicode=>1, |
|
362
|
|
|
|
|
|
|
# the latter behaviour is the default. but setting the opposite of above will set it. |
|
363
|
|
|
|
|
|
|
# NOTE: there are 2 alternatives to this |
|
364
|
|
|
|
|
|
|
# perl2dump_filtered() which uses Data::Dump filters to control unicode escaping but |
|
365
|
|
|
|
|
|
|
# lacks in aesthetics and functionality and handling all the cases Dump and Dumper |
|
366
|
|
|
|
|
|
|
# do quite well. |
|
367
|
|
|
|
|
|
|
# perl2dump_homebrew() uses the same dump-recursively engine but does not involve |
|
368
|
|
|
|
|
|
|
# Data::Dump at all. |
|
369
|
|
|
|
|
|
|
sub perl2dump { |
|
370
|
34
|
|
|
34
|
1
|
44468
|
my $pv = $_[0]; |
|
371
|
34
|
100
|
|
|
|
102
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
local $Data::Dumper::Terse = exists($params->{'terse'}) && defined($params->{'terse'}) |
|
374
|
34
|
100
|
66
|
|
|
194
|
? $params->{'terse'} : 0 |
|
375
|
|
|
|
|
|
|
; |
|
376
|
|
|
|
|
|
|
local $Data::Dumper::Indent = exists($params->{'indent'}) && defined($params->{'indent'}) |
|
377
|
34
|
100
|
66
|
|
|
137
|
? $params->{'indent'} : 1 |
|
378
|
|
|
|
|
|
|
; |
|
379
|
|
|
|
|
|
|
|
|
380
|
34
|
50
|
100
|
|
|
283
|
if( ($_permanent_override == 0) |
|
|
|
|
100
|
|
|
|
|
|
381
|
|
|
|
|
|
|
&& (( |
|
382
|
|
|
|
|
|
|
exists($params->{'dont-bloody-escape-unicode'}) && defined($params->{'dont-bloody-escape-unicode'}) |
|
383
|
|
|
|
|
|
|
&& ($params->{'dont-bloody-escape-unicode'}==1) |
|
384
|
|
|
|
|
|
|
) || ( |
|
385
|
|
|
|
|
|
|
exists($params->{'escape-unicode'}) && defined($params->{'escape-unicode'}) |
|
386
|
|
|
|
|
|
|
&& ($params->{'escape-unicode'}==0) |
|
387
|
|
|
|
|
|
|
) |
|
388
|
|
|
|
|
|
|
) |
|
389
|
|
|
|
|
|
|
){ |
|
390
|
|
|
|
|
|
|
# this is the case where no 'no-unicode-escape-permanently' |
|
391
|
|
|
|
|
|
|
# was used at loading the module |
|
392
|
|
|
|
|
|
|
# we have to use the special qquote each time caller |
|
393
|
|
|
|
|
|
|
# sets 'dont-bloody-escape-unicode'=>1 |
|
394
|
|
|
|
|
|
|
# which will be replaced with the original sub |
|
395
|
|
|
|
|
|
|
# once we exit this scope. |
|
396
|
|
|
|
|
|
|
# make benchmarks will compare all cases if you ever |
|
397
|
|
|
|
|
|
|
# want to get more efficiency out of this |
|
398
|
18
|
|
|
|
|
38
|
local $Data::Dumper::Useperl = 1; |
|
399
|
18
|
|
|
|
|
52
|
local $Data::Dumper::Useqq='utf8'; |
|
400
|
9
|
|
|
9
|
|
82
|
no warnings 'redefine'; |
|
|
9
|
|
|
|
|
22
|
|
|
|
9
|
|
|
|
|
14242
|
|
|
401
|
18
|
|
|
|
|
78
|
local *Data::Dumper::qquote = \& _qquote_redefinition_by_Corion; |
|
402
|
18
|
|
|
|
|
71
|
return Data::Dumper::Dumper($pv); |
|
403
|
|
|
|
|
|
|
# out of scope local's will be restored to original values |
|
404
|
|
|
|
|
|
|
} |
|
405
|
16
|
|
|
|
|
73
|
return Data::Dumper::Dumper($pv) |
|
406
|
|
|
|
|
|
|
} |
|
407
|
|
|
|
|
|
|
# This uses Data::Dump's filters |
|
408
|
|
|
|
|
|
|
# The _qquote_redefinition_by_Corion() code is by [Corion] @ Perlmonks and cpan |
|
409
|
|
|
|
|
|
|
# see https://perlmonks.org/?node_id=11115271 |
|
410
|
|
|
|
|
|
|
sub perl2dump_filtered { |
|
411
|
14
|
|
|
14
|
1
|
66302
|
my $pv = $_[0]; |
|
412
|
14
|
100
|
|
|
|
57
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
413
|
|
|
|
|
|
|
|
|
414
|
14
|
50
|
100
|
|
|
143
|
if( ($_permanent_filter == 0) |
|
|
|
|
100
|
|
|
|
|
|
415
|
|
|
|
|
|
|
&& (( |
|
416
|
|
|
|
|
|
|
exists($params->{'dont-bloody-escape-unicode'}) && defined($params->{'dont-bloody-escape-unicode'}) |
|
417
|
|
|
|
|
|
|
&& ($params->{'dont-bloody-escape-unicode'}==1) |
|
418
|
|
|
|
|
|
|
) || ( |
|
419
|
|
|
|
|
|
|
exists($params->{'escape-unicode'}) && defined($params->{'escape-unicode'}) |
|
420
|
|
|
|
|
|
|
&& ($params->{'escape-unicode'}==0) |
|
421
|
|
|
|
|
|
|
) |
|
422
|
|
|
|
|
|
|
) |
|
423
|
|
|
|
|
|
|
){ |
|
424
|
4
|
|
|
|
|
29
|
Data::Dump::Filtered::add_dump_filter( \& DataDumpFilterino ); |
|
425
|
4
|
|
|
|
|
61
|
my $ret = Data::Dump::pp($pv); |
|
426
|
4
|
|
|
|
|
374
|
Data::Dump::Filtered::remove_dump_filter( \& DataDumpFilterino ); |
|
427
|
4
|
|
|
|
|
39
|
return $ret; |
|
428
|
|
|
|
|
|
|
} |
|
429
|
10
|
|
|
|
|
55
|
return Data::Dump::pp($pv); |
|
430
|
|
|
|
|
|
|
} |
|
431
|
|
|
|
|
|
|
sub perl2dump_homebrew { |
|
432
|
5
|
|
|
5
|
1
|
2573
|
my $pv = $_[0]; |
|
433
|
5
|
100
|
|
|
|
19
|
my $params = defined($_[1]) ? $_[1] : {}; |
|
434
|
|
|
|
|
|
|
|
|
435
|
5
|
50
|
66
|
|
|
86
|
if( ($_permanent_override == 1) |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
436
|
|
|
|
|
|
|
|| ( |
|
437
|
|
|
|
|
|
|
exists($params->{'dont-bloody-escape-unicode'}) && defined($params->{'dont-bloody-escape-unicode'}) |
|
438
|
|
|
|
|
|
|
&& ($params->{'dont-bloody-escape-unicode'}==1) |
|
439
|
|
|
|
|
|
|
) || ( |
|
440
|
|
|
|
|
|
|
exists($params->{'escape-unicode'}) && defined($params->{'escape-unicode'}) |
|
441
|
|
|
|
|
|
|
&& ($params->{'escape-unicode'}==0) |
|
442
|
|
|
|
|
|
|
) |
|
443
|
|
|
|
|
|
|
){ |
|
444
|
3
|
|
|
|
|
16
|
return dump_perl_var_recursively($pv); |
|
445
|
|
|
|
|
|
|
} |
|
446
|
2
|
|
|
|
|
10
|
return Data::Dumper::Dumper($pv); |
|
447
|
|
|
|
|
|
|
} |
|
448
|
|
|
|
|
|
|
# this will take a perl var (as a scalar or an arbitrarily nested data structure) |
|
449
|
|
|
|
|
|
|
# and emulate a very very basic |
|
450
|
|
|
|
|
|
|
# Dump/Dumper but with rendering unicode (for keys or values or array items) |
|
451
|
|
|
|
|
|
|
# it returns a string representation of the input perl var |
|
452
|
|
|
|
|
|
|
# There are 2 obvious limitations: |
|
453
|
|
|
|
|
|
|
# 1) indentation is very basic, |
|
454
|
|
|
|
|
|
|
# 2) it supports only scalars, hashes and arrays, |
|
455
|
|
|
|
|
|
|
# (which will dive into them no problem) |
|
456
|
|
|
|
|
|
|
# This sub can be used in conjuction with DataDumpFilterino() |
|
457
|
|
|
|
|
|
|
# to create a Data::Dump filter like, |
|
458
|
|
|
|
|
|
|
# Data::Dump::Filtered::add_dump_filter( \& DataDumpFilterino ); |
|
459
|
|
|
|
|
|
|
# or dumpf($perl_var, \& DataDumpFilterino); |
|
460
|
|
|
|
|
|
|
# the input is a perl-var as a reference, so no %inp but $inp={} or $inp=[] |
|
461
|
|
|
|
|
|
|
# the output is a, possibly multiline, string |
|
462
|
|
|
|
|
|
|
sub dump_perl_var_recursively { |
|
463
|
378
|
|
|
378
|
1
|
601
|
my $inp = $_[0]; |
|
464
|
378
|
100
|
|
|
|
571
|
my $depth = defined($_[1]) ? $_[1] : 0; |
|
465
|
378
|
|
|
|
|
495
|
my $aref = ref($inp); |
|
466
|
378
|
100
|
|
|
|
606
|
if( $aref eq '' ){ |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
# scalar |
|
468
|
368
|
|
|
|
|
533
|
return _qquote_redefinition_by_Corion($inp); |
|
469
|
|
|
|
|
|
|
} elsif( $aref eq 'SCALAR' ){ |
|
470
|
|
|
|
|
|
|
# scalar |
|
471
|
0
|
|
|
|
|
0
|
return _qquote_redefinition_by_Corion($$inp); |
|
472
|
|
|
|
|
|
|
} elsif( $aref eq 'HASH' ){ |
|
473
|
4
|
|
|
|
|
13
|
my $indent1 = ' 'x((2+$depth)*2); |
|
474
|
4
|
|
|
|
|
10
|
my $indent2 = $indent1 x 2; |
|
475
|
4
|
|
|
|
|
10
|
my $retdump= "\n".$indent1.'{'."\n"; |
|
476
|
4
|
|
|
|
|
16
|
for my $k (keys %$inp){ |
|
477
|
|
|
|
|
|
|
$retdump .= $indent2 |
|
478
|
|
|
|
|
|
|
. _qquote_redefinition_by_Corion($k) |
|
479
|
|
|
|
|
|
|
." => " |
|
480
|
4
|
|
|
|
|
12
|
. dump_perl_var_recursively($inp->{$k}, $depth+1) |
|
481
|
|
|
|
|
|
|
.",\n" |
|
482
|
|
|
|
|
|
|
; |
|
483
|
|
|
|
|
|
|
} |
|
484
|
4
|
|
|
|
|
24
|
return $retdump. $indent1 . '}' |
|
485
|
|
|
|
|
|
|
} elsif( $aref eq 'ARRAY' ){ |
|
486
|
6
|
|
|
|
|
20
|
my $indent1 = ' ' x ((1+$depth)*2); |
|
487
|
6
|
|
|
|
|
17
|
my $indent2 = $indent1 x 2; |
|
488
|
6
|
|
|
|
|
16
|
my $retdump= "\n".$indent1.'['."\n"; |
|
489
|
6
|
|
|
|
|
12
|
for my $v (@$inp){ |
|
490
|
364
|
|
|
|
|
693
|
$retdump .= |
|
491
|
|
|
|
|
|
|
$indent2 |
|
492
|
|
|
|
|
|
|
. dump_perl_var_recursively($v, $depth+1) |
|
493
|
|
|
|
|
|
|
.",\n" |
|
494
|
|
|
|
|
|
|
; |
|
495
|
|
|
|
|
|
|
} |
|
496
|
6
|
|
|
|
|
52
|
return $retdump. $indent1 . ']' |
|
497
|
|
|
|
|
|
|
} else { |
|
498
|
0
|
|
|
|
|
0
|
my $indent1 = ' ' x ((1+$depth)*2); |
|
499
|
0
|
|
|
|
|
0
|
return $indent1 . $inp .",\n" |
|
500
|
|
|
|
|
|
|
} |
|
501
|
|
|
|
|
|
|
} |
|
502
|
|
|
|
|
|
|
sub DataDumpFilterino { |
|
503
|
7
|
|
|
7
|
1
|
4882
|
my($ctx, $object_ref) = @_; |
|
504
|
7
|
|
|
|
|
18
|
my $aref = ref($object_ref); |
|
505
|
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
return { |
|
507
|
7
|
|
|
|
|
24
|
'dump' => dump_perl_var_recursively($object_ref, $ctx->depth) |
|
508
|
|
|
|
|
|
|
} |
|
509
|
|
|
|
|
|
|
} |
|
510
|
|
|
|
|
|
|
# opens file, |
|
511
|
|
|
|
|
|
|
# reads all content of file and returns them on success |
|
512
|
|
|
|
|
|
|
# or returns undef on failure |
|
513
|
|
|
|
|
|
|
# the file is closed in either case |
|
514
|
|
|
|
|
|
|
sub read_from_file { |
|
515
|
8
|
|
|
8
|
1
|
71
|
my $infile = $_[0]; |
|
516
|
8
|
|
|
|
|
12
|
my $FH; |
|
517
|
8
|
50
|
|
1
|
|
337
|
if( ! open $FH, '<:encoding(UTF-8)', $infile ){ |
|
|
1
|
|
|
|
|
15
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
7
|
|
|
518
|
0
|
|
|
|
|
0
|
warn "failed to open file '$infile' for reading, $!"; |
|
519
|
0
|
|
|
|
|
0
|
return undef; |
|
520
|
|
|
|
|
|
|
} |
|
521
|
8
|
|
|
|
|
2012
|
my $contents = read_from_filehandle($FH); |
|
522
|
8
|
|
|
|
|
407
|
close $FH; |
|
523
|
8
|
|
|
|
|
63
|
return $contents |
|
524
|
|
|
|
|
|
|
} |
|
525
|
|
|
|
|
|
|
# writes contents to file and returns 0 on failure, 1 on success |
|
526
|
|
|
|
|
|
|
sub write_to_file { |
|
527
|
0
|
|
|
0
|
1
|
0
|
my $outfile = $_[0]; |
|
528
|
0
|
|
|
|
|
0
|
my $contents = $_[1]; |
|
529
|
0
|
|
|
|
|
0
|
my $FH; |
|
530
|
0
|
0
|
|
|
|
0
|
if( ! open $FH, '>:encoding(UTF-8)', $outfile ){ |
|
531
|
0
|
|
|
|
|
0
|
warn "failed to open file '$outfile' for writing, $!"; |
|
532
|
0
|
|
|
|
|
0
|
return 0 |
|
533
|
|
|
|
|
|
|
} |
|
534
|
0
|
0
|
|
|
|
0
|
if( ! write_to_filehandle($FH, $contents) ){ warn "error, call to ".'write_to_filehandle()'." has failed"; close $FH; return 0 } |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
535
|
0
|
|
|
|
|
0
|
close $FH; |
|
536
|
0
|
|
|
|
|
0
|
return 1; |
|
537
|
|
|
|
|
|
|
} |
|
538
|
|
|
|
|
|
|
# reads all content from filehandle and returns them on success |
|
539
|
|
|
|
|
|
|
# or returns undef on failure |
|
540
|
|
|
|
|
|
|
sub read_from_filehandle { |
|
541
|
8
|
|
|
8
|
1
|
16
|
my $FH = $_[0]; |
|
542
|
|
|
|
|
|
|
# you should open INFH as '<:encoding(UTF-8)' |
|
543
|
|
|
|
|
|
|
# or if it is STDIN, do binmode STDIN , ':encoding(UTF-8)'; |
|
544
|
8
|
|
|
|
|
13
|
return do { local $/; <$FH> } |
|
|
8
|
|
|
|
|
38
|
|
|
|
8
|
|
|
|
|
331
|
|
|
545
|
|
|
|
|
|
|
} |
|
546
|
|
|
|
|
|
|
sub write_to_filehandle { |
|
547
|
0
|
|
|
0
|
1
|
0
|
my $FH = $_[0]; |
|
548
|
0
|
|
|
|
|
0
|
my $contents = $_[1]; |
|
549
|
|
|
|
|
|
|
# you should open $OUTFH as >:encoding(UTF-8)' |
|
550
|
|
|
|
|
|
|
# or if it is STDOUT, do binmode STDOUT , ':encoding(UTF-8)'; |
|
551
|
0
|
|
|
|
|
0
|
print $FH $contents; |
|
552
|
0
|
|
|
|
|
0
|
return 1; |
|
553
|
|
|
|
|
|
|
} |
|
554
|
|
|
|
|
|
|
# todo: change to utf8::is_utf8() |
|
555
|
42
|
|
|
42
|
|
308
|
sub _has_utf8 { return $_[0] =~ /[^\x00-\x7f]/ } |
|
556
|
|
|
|
|
|
|
# Below code is by [Corion] @ Perlmonks and cpan |
|
557
|
|
|
|
|
|
|
# see https://perlmonks.org/?node_id=11115271 |
|
558
|
|
|
|
|
|
|
# it's for redefining Data::Dumper::qquote |
|
559
|
|
|
|
|
|
|
# (it must be accompanied by |
|
560
|
|
|
|
|
|
|
# $Data::Dumper::Useperl = 1; |
|
561
|
|
|
|
|
|
|
# $Data::Dumper::Useqq='utf8'; |
|
562
|
|
|
|
|
|
|
# HOWEVER, I discoverd that a redefined sub can not access packages private vars |
|
563
|
|
|
|
|
|
|
sub _qquote_redefinition_by_Corion { |
|
564
|
568
|
|
|
568
|
|
17956
|
local($_) = shift; |
|
565
|
|
|
|
|
|
|
|
|
566
|
568
|
50
|
|
|
|
1034
|
return qq("") unless defined $_; |
|
567
|
568
|
|
|
|
|
1853
|
s/([\\\"\@\$])/\\$1/g; |
|
568
|
|
|
|
|
|
|
|
|
569
|
568
|
100
|
|
|
|
2707
|
return qq("$_") unless /[[:^print:]]/; # fast exit if only printables |
|
570
|
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
# Here, there is at least one non-printable to output. First, translate the |
|
572
|
|
|
|
|
|
|
# escapes. |
|
573
|
2
|
|
|
|
|
22
|
s/([\a\b\t\n\f\r\e])/$Data_Dumper_esc{$1}/g; |
|
574
|
|
|
|
|
|
|
# this is the original but it does not work because it can't find %esc |
|
575
|
|
|
|
|
|
|
# which is a private var in Data::Dumper, so I copied those vars above |
|
576
|
|
|
|
|
|
|
# and access them as Data_Dumper_XYZ |
|
577
|
|
|
|
|
|
|
#s/([\a\b\t\n\f\r\e])/$Data::Dumper::esc{$1}/g; |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
# no need for 3 digits in escape for octals not followed by a digit. |
|
580
|
2
|
|
|
|
|
38
|
s/($Data_Dumper_low_controls)(?!\d)/'\\'.sprintf('%o',ord($1))/eg; |
|
|
0
|
|
|
|
|
0
|
|
|
581
|
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
# But otherwise use 3 digits |
|
583
|
2
|
|
|
|
|
22
|
s/($Data_Dumper_low_controls)/'\\'.sprintf('%03o',ord($1))/eg; |
|
|
0
|
|
|
|
|
0
|
|
|
584
|
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
# all but last branch below not supported --BEHAVIOR SUBJECT TO CHANGE-- |
|
587
|
2
|
|
50
|
|
|
11
|
my $high = shift || ""; |
|
588
|
2
|
50
|
|
|
|
10
|
if ($high eq "iso8859") { # Doesn't escape the Latin1 printables |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
589
|
0
|
0
|
|
|
|
0
|
if ($Data_Dumper_IS_ASCII) { |
|
|
|
0
|
|
|
|
|
|
|
590
|
0
|
|
|
|
|
0
|
s/([\200-\240])/'\\'.sprintf('%o',ord($1))/eg; |
|
|
0
|
|
|
|
|
0
|
|
|
591
|
|
|
|
|
|
|
} |
|
592
|
|
|
|
|
|
|
elsif ($] ge 5.007_003) { |
|
593
|
0
|
|
|
|
|
0
|
my $high_control = utf8::unicode_to_native(0x9F); |
|
594
|
0
|
|
|
|
|
0
|
s/$high_control/sprintf('\\%o',ord($1))/eg; |
|
|
0
|
|
|
|
|
0
|
|
|
595
|
|
|
|
|
|
|
} |
|
596
|
|
|
|
|
|
|
} elsif ($high eq "utf8") { |
|
597
|
|
|
|
|
|
|
# Some discussion of what to do here is in |
|
598
|
|
|
|
|
|
|
# https://rt.perl.org/Ticket/Display.html?id=113088 |
|
599
|
|
|
|
|
|
|
# use utf8; |
|
600
|
|
|
|
|
|
|
# $str =~ s/([^\040-\176])/sprintf "\\x{%04x}", ord($1)/ge; |
|
601
|
|
|
|
|
|
|
} elsif ($high eq "8bit") { |
|
602
|
|
|
|
|
|
|
# leave it as it is |
|
603
|
|
|
|
|
|
|
} else { |
|
604
|
0
|
|
|
|
|
0
|
s/([[:^ascii:]])/'\\'.sprintf('%03o',ord($1))/eg; |
|
|
0
|
|
|
|
|
0
|
|
|
605
|
|
|
|
|
|
|
#s/([^\040-\176])/sprintf "\\x{%04x}", ord($1)/ge; |
|
606
|
|
|
|
|
|
|
} |
|
607
|
2
|
|
|
|
|
29
|
return qq("$_"); |
|
608
|
|
|
|
|
|
|
} |
|
609
|
|
|
|
|
|
|
# begin pod |
|
610
|
|
|
|
|
|
|
=pod |
|
611
|
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
=encoding utf8 |
|
613
|
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
=head1 NAME |
|
615
|
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
Data::Roundtrip - convert between Perl data structures, YAML and JSON with unicode support (I believe ...) |
|
617
|
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
=head1 VERSION |
|
619
|
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
Version 0.20 |
|
621
|
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
623
|
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
This module contains a collection of utilities for converting between |
|
625
|
|
|
|
|
|
|
JSON, YAML, Perl variable and a Perl variable's string representation (aka dump). |
|
626
|
|
|
|
|
|
|
Hopefully, all unicode content will be handled correctly between |
|
627
|
|
|
|
|
|
|
the conversions and optionally escaped or un-escaped. Also JSON can |
|
628
|
|
|
|
|
|
|
be presented in a pretty format or in a condensed, machine-readable |
|
629
|
|
|
|
|
|
|
format (not spaces, indendation or line breaks). |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
use Data::Roundtrip qw/:all/; |
|
632
|
|
|
|
|
|
|
#use Data::Roundtrip qw/json2yaml/; |
|
633
|
|
|
|
|
|
|
#use Data::Roundtrip qw/:json/; # see EXPORT |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
$jsonstr = '{"Songname": "Απόκληρος της κοινωνίας",' |
|
636
|
|
|
|
|
|
|
.'"Artist": "Καζαντζίδης Στέλιος/Βίρβος Κώστας"}' |
|
637
|
|
|
|
|
|
|
; |
|
638
|
|
|
|
|
|
|
$yamlstr = json2yaml($jsonstr); |
|
639
|
|
|
|
|
|
|
print $yamlstr; |
|
640
|
|
|
|
|
|
|
# NOTE: long strings have been broken into multilines |
|
641
|
|
|
|
|
|
|
# and/or truncated (replaced with ...) |
|
642
|
|
|
|
|
|
|
#--- |
|
643
|
|
|
|
|
|
|
#Artist: Καζαντζίδης Στέλιος/Βίρβος Κώστας |
|
644
|
|
|
|
|
|
|
#Songname: Απόκληρος της κοινωνίας |
|
645
|
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
$yamlstr = json2yaml($jsonstr, {'escape-unicode'=>1}); |
|
647
|
|
|
|
|
|
|
print $yamlstr; |
|
648
|
|
|
|
|
|
|
#--- |
|
649
|
|
|
|
|
|
|
#Artist: \u039a\u03b1\u03b6\u03b1 ... |
|
650
|
|
|
|
|
|
|
#Songname: \u0391\u03c0\u03cc\u03ba ... |
|
651
|
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
$backtojson = yaml2json($yamlstr); |
|
653
|
|
|
|
|
|
|
# $backtojson is a string representation |
|
654
|
|
|
|
|
|
|
# of following JSON structure: |
|
655
|
|
|
|
|
|
|
# {"Artist":"Καζαντζίδης Στέλιος/Βίρβος Κώστας", |
|
656
|
|
|
|
|
|
|
# "Songname":"Απόκληρος της κοινωνίας"} |
|
657
|
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
# This is useful when sending JSON via |
|
659
|
|
|
|
|
|
|
# a POST request and it needs unicode escaped: |
|
660
|
|
|
|
|
|
|
$backtojson = yaml2json($yamlstr, {'escape-unicode'=>1}); |
|
661
|
|
|
|
|
|
|
# $backtojson is a string representation |
|
662
|
|
|
|
|
|
|
# of following JSON structure: |
|
663
|
|
|
|
|
|
|
# but this time with unicode escaped |
|
664
|
|
|
|
|
|
|
# (pod content truncated for readbility) |
|
665
|
|
|
|
|
|
|
# {"Artist":"\u039a\u03b1\u03b6 ...", |
|
666
|
|
|
|
|
|
|
# "Songname":"\u0391\u03c0\u03cc ..."} |
|
667
|
|
|
|
|
|
|
# this is the usual Data::Dumper dump: |
|
668
|
|
|
|
|
|
|
print json2dump($jsonstr); |
|
669
|
|
|
|
|
|
|
#$VAR1 = { |
|
670
|
|
|
|
|
|
|
# 'Songname' => "\x{391}\x{3c0}\x{3cc} ...", |
|
671
|
|
|
|
|
|
|
# 'Artist' => "\x{39a}\x{3b1}\x{3b6} ...", |
|
672
|
|
|
|
|
|
|
#}; |
|
673
|
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
# and this is a more human-readable version: |
|
675
|
|
|
|
|
|
|
print json2dump($jsonstr, {'dont-bloody-escape-unicode'=>1}); |
|
676
|
|
|
|
|
|
|
# $VAR1 = { |
|
677
|
|
|
|
|
|
|
# "Artist" => "Καζαντζίδης Στέλιος/Βίρβος Κώστας", |
|
678
|
|
|
|
|
|
|
# "Songname" => "Απόκληρος της κοινωνίας" |
|
679
|
|
|
|
|
|
|
# }; |
|
680
|
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
# pass some parameters to Data::Dumper |
|
682
|
|
|
|
|
|
|
# like: be terse (no $VAR1): |
|
683
|
|
|
|
|
|
|
print json2dump($jsonstr, |
|
684
|
|
|
|
|
|
|
{'dont-bloody-escape-unicode'=>0, 'terse'=>1} |
|
685
|
|
|
|
|
|
|
#{'dont-bloody-escape-unicode'=>0, 'terse'=>1, 'indent'=>0} |
|
686
|
|
|
|
|
|
|
); |
|
687
|
|
|
|
|
|
|
# { |
|
688
|
|
|
|
|
|
|
# "Artist" => "Καζαντζίδης Στέλιος/Βίρβος Κώστας", |
|
689
|
|
|
|
|
|
|
# "Songname" => "Απόκληρος της κοινωνίας" |
|
690
|
|
|
|
|
|
|
# } |
|
691
|
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
# this is how to reformat a JSON string to |
|
693
|
|
|
|
|
|
|
# have its unicode content escaped: |
|
694
|
|
|
|
|
|
|
my $json_with_unicode_escaped = |
|
695
|
|
|
|
|
|
|
json2json($jsonstr, {'escape-unicode'=>1}); |
|
696
|
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
# With version 0.18 and up two more exported-on-demand |
|
698
|
|
|
|
|
|
|
# subs were added to read JSON or YAML directly from a file: |
|
699
|
|
|
|
|
|
|
# jsonfile2perl() and yamlfile2perl() |
|
700
|
|
|
|
|
|
|
my $perldata = jsonfile2perl("file.json"); |
|
701
|
|
|
|
|
|
|
my $perldata = yamlfile2perl("file.yaml"); |
|
702
|
|
|
|
|
|
|
die "failed" unless defined $perldata; |
|
703
|
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
# For some of the above functions there exist command-line scripts: |
|
705
|
|
|
|
|
|
|
perl2json.pl -i "perl-data-structure.pl" -o "output.json" --pretty |
|
706
|
|
|
|
|
|
|
json2json.pl -i "with-unicode.json" -o "unicode-escaped.json" --escape-unicode |
|
707
|
|
|
|
|
|
|
# etc. |
|
708
|
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
# only for *2dump: perl2dump, json2dump, yaml2dump |
|
710
|
|
|
|
|
|
|
# and if no escape-unicode is required (i.e. |
|
711
|
|
|
|
|
|
|
# setting 'dont-bloody-escape-unicode' => 1 permanently) |
|
712
|
|
|
|
|
|
|
# and if efficiency is important, |
|
713
|
|
|
|
|
|
|
# meaning that perl2dump is run in a loop thousand of times, |
|
714
|
|
|
|
|
|
|
# then import the module like this: |
|
715
|
|
|
|
|
|
|
use Data::Roundtrip qw/:all no-unicode-escape-permanently/; |
|
716
|
|
|
|
|
|
|
# or like this |
|
717
|
|
|
|
|
|
|
use Data::Roundtrip qw/:all unicode-escape-permanently/; |
|
718
|
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
# then perl2dump() is more efficient but unicode characters |
|
720
|
|
|
|
|
|
|
# will be permanently not-escaped (1st case) or escaped (2nd case). |
|
721
|
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
=head1 EXPORT |
|
723
|
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
By default no symbols are exported. However, the following export tags are available (:all will export all of them): |
|
725
|
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
=over 4 |
|
727
|
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
=item * C<:json> : |
|
729
|
|
|
|
|
|
|
C, |
|
730
|
|
|
|
|
|
|
C, |
|
731
|
|
|
|
|
|
|
C, |
|
732
|
|
|
|
|
|
|
C, |
|
733
|
|
|
|
|
|
|
C, |
|
734
|
|
|
|
|
|
|
C |
|
735
|
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
=item * C<:yaml> : |
|
737
|
|
|
|
|
|
|
C, |
|
738
|
|
|
|
|
|
|
C, |
|
739
|
|
|
|
|
|
|
C, |
|
740
|
|
|
|
|
|
|
C, |
|
741
|
|
|
|
|
|
|
C, |
|
742
|
|
|
|
|
|
|
C |
|
743
|
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
=item * C<:dump> : |
|
745
|
|
|
|
|
|
|
C, |
|
746
|
|
|
|
|
|
|
C, |
|
747
|
|
|
|
|
|
|
C, |
|
748
|
|
|
|
|
|
|
C, |
|
749
|
|
|
|
|
|
|
C, |
|
750
|
|
|
|
|
|
|
C |
|
751
|
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
=item * C<:io> : |
|
753
|
|
|
|
|
|
|
C, C, |
|
754
|
|
|
|
|
|
|
C, C, |
|
755
|
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
=item * C<:all> : everything above |
|
757
|
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
=item * C : this is not an |
|
759
|
|
|
|
|
|
|
export keyword/parameter but a parameter which affects |
|
760
|
|
|
|
|
|
|
all the C<< *2dump* >> subs by setting unicode escaping |
|
761
|
|
|
|
|
|
|
permanently to false. See L. |
|
762
|
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
=item * C : this is not an |
|
764
|
|
|
|
|
|
|
export keyword/parameter but a parameter which affects |
|
765
|
|
|
|
|
|
|
all the C<< *2dump* >> subs by setting unicode escaping |
|
766
|
|
|
|
|
|
|
permanently to true. See L. |
|
767
|
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
=back |
|
769
|
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
=head1 EFFICIENCY |
|
771
|
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
The export keyword/parameter C<< no-unicode-escape-permanently >> |
|
773
|
|
|
|
|
|
|
affects |
|
774
|
|
|
|
|
|
|
all the C<< *2dump* >> subs by setting unicode escaping |
|
775
|
|
|
|
|
|
|
permanently to false. This improves efficiency, although |
|
776
|
|
|
|
|
|
|
one will ever need to |
|
777
|
|
|
|
|
|
|
use this in extreme situations where a C<< *2dump* >> |
|
778
|
|
|
|
|
|
|
sub is called repeatedly in a loop of |
|
779
|
|
|
|
|
|
|
a few hundreds or thousands of iterations or more. |
|
780
|
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
Each time a C<< *2dump* >> is called, the |
|
782
|
|
|
|
|
|
|
C<< dont-bloody-escape-unicode >> flag is checked |
|
783
|
|
|
|
|
|
|
and if it is set, then L's C<< qquote() >> |
|
784
|
|
|
|
|
|
|
is overriden with C<< _qquote_redefinition_by_Corion() >> |
|
785
|
|
|
|
|
|
|
just for that instance and will be restored as soon as |
|
786
|
|
|
|
|
|
|
the dump is finished. Similarly, a filter for |
|
787
|
|
|
|
|
|
|
not escaping unicode is added to L |
|
788
|
|
|
|
|
|
|
just for that particular call and is removed immediately |
|
789
|
|
|
|
|
|
|
after. This has some computational cost and can be |
|
790
|
|
|
|
|
|
|
avoided completely by overriding the sub |
|
791
|
|
|
|
|
|
|
and adding the filter once, at loading (in C<< import() >>). |
|
792
|
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
The price to pay for this added efficiency is that |
|
794
|
|
|
|
|
|
|
unicode in any dump will never be escaped (e.g. C<< \x{3b1}) >>, |
|
795
|
|
|
|
|
|
|
but will be rendered (e.g. C<< α >>, a greek alpha). Always. |
|
796
|
|
|
|
|
|
|
The option |
|
797
|
|
|
|
|
|
|
C<< dont-bloody-escape-unicode >> will permanently be set to true. |
|
798
|
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
Similarly, the export keyword/parameter |
|
800
|
|
|
|
|
|
|
C<< unicode-escape-permanently >> |
|
801
|
|
|
|
|
|
|
affects |
|
802
|
|
|
|
|
|
|
all the C<< *2dump* >> subs by setting unicode escaping |
|
803
|
|
|
|
|
|
|
permanently to true. This improves efficiency as well. |
|
804
|
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
See L on how to find the fastest C<< *2dump* >> |
|
806
|
|
|
|
|
|
|
sub. |
|
807
|
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
=head1 BENCHMARKS |
|
809
|
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
The special Makefile target C<< benchmarks >> will time |
|
811
|
|
|
|
|
|
|
calls to each of the C<< *2dump* >> subs under |
|
812
|
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
use Data::Roundtrip; |
|
814
|
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
use Data::Roundtrip qw/no-unicode-escape-permanently/; |
|
816
|
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
use Data::Roundtrip qw/unicode-escape-permanently/; |
|
818
|
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
and for C<< 'dont-bloody-escape-unicode' => 0 >> and |
|
820
|
|
|
|
|
|
|
C<< 'dont-bloody-escape-unicode' => 1 >>. |
|
821
|
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
In general, L is faster by 25% when one of the |
|
823
|
|
|
|
|
|
|
permanent import parameters is used |
|
824
|
|
|
|
|
|
|
(either of the last two cases above). |
|
825
|
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
=head1 SUBROUTINES |
|
827
|
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
=head2 C |
|
829
|
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
my $ret = perl2json($perlvar, $optional_paramshashref) |
|
831
|
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
Arguments: |
|
833
|
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
=over 4 |
|
835
|
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
=item * C<$perlvar> |
|
837
|
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
=item * C<$optional_paramshashref> |
|
839
|
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
=back |
|
841
|
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
Return value: |
|
843
|
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
=over 4 |
|
845
|
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
=item * C<$ret> |
|
847
|
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
=back |
|
849
|
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
Given an input C<$perlvar> (which can be a simple scalar or |
|
851
|
|
|
|
|
|
|
a nested data structure, but not an object), it will return |
|
852
|
|
|
|
|
|
|
the equivalent JSON string. In C<$optional_paramshashref> |
|
853
|
|
|
|
|
|
|
one can specify whether to escape unicode with |
|
854
|
|
|
|
|
|
|
C<< 'escape-unicode' => 1 >> |
|
855
|
|
|
|
|
|
|
and/or prettify the returned result with C<< 'pretty' => 1 >>. |
|
856
|
|
|
|
|
|
|
The output can be fed back to L |
|
857
|
|
|
|
|
|
|
for getting the Perl variable back. |
|
858
|
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
Returns the JSON string on success or C on failure. |
|
860
|
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
=head2 C |
|
862
|
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
Arguments: |
|
864
|
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
=over 4 |
|
866
|
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
=item * C<$jsonstring> |
|
868
|
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
=back |
|
870
|
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
Return value: |
|
872
|
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
=over 4 |
|
874
|
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
=item * C<$ret> |
|
876
|
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
=back |
|
878
|
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
Given an input C<$jsonstring> as a string, it will return |
|
880
|
|
|
|
|
|
|
the equivalent Perl data structure using |
|
881
|
|
|
|
|
|
|
C. |
|
882
|
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
Returns the Perl data structure on success or C on failure. |
|
884
|
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
=head2 C |
|
886
|
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
my $ret = perl2yaml($perlvar, $optional_paramshashref) |
|
888
|
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
Arguments: |
|
890
|
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
=over 4 |
|
892
|
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
=item * C<$perlvar> |
|
894
|
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
=item * C<$optional_paramshashref> |
|
896
|
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
=back |
|
898
|
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
Return value: |
|
900
|
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
=over 4 |
|
902
|
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
=item * C<$ret> |
|
904
|
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
=back |
|
906
|
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
Given an input C<$perlvar> (which can be a simple scalar or |
|
908
|
|
|
|
|
|
|
a nested data structure, but not an object), it will return |
|
909
|
|
|
|
|
|
|
the equivalent YAML string. In C<$optional_paramshashref> |
|
910
|
|
|
|
|
|
|
one can specify whether to escape unicode with |
|
911
|
|
|
|
|
|
|
C<< 'escape-unicode' => 1 >>. Prettify is not supported yet. |
|
912
|
|
|
|
|
|
|
The output can be fed to L |
|
913
|
|
|
|
|
|
|
for getting the Perl variable back. |
|
914
|
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
Returns the YAML string on success or C on failure. |
|
916
|
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
=head2 C |
|
918
|
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
my $ret = yaml2perl($yamlstring); |
|
920
|
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
Arguments: |
|
922
|
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
=over 4 |
|
924
|
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
=item * C<$yamlstring> |
|
926
|
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
=back |
|
928
|
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
Return value: |
|
930
|
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
=over 4 |
|
932
|
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
=item * C<$ret> |
|
934
|
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
=back |
|
936
|
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
Given an input C<$yamlstring> as a string, it will return |
|
938
|
|
|
|
|
|
|
the equivalent Perl data structure using |
|
939
|
|
|
|
|
|
|
C |
|
940
|
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
Returns the Perl data structure on success or C on failure. |
|
942
|
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
=head2 C |
|
944
|
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
my $ret = yamlfile2perl($filename) |
|
946
|
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
Arguments: |
|
948
|
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
=over 4 |
|
950
|
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
=item * C<$filename> |
|
952
|
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
=back |
|
954
|
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
Return value: |
|
956
|
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
=over 4 |
|
958
|
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
=item * C<$ret> |
|
960
|
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=back |
|
962
|
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
Given an input C<$filename> which points to a file containing YAML content, |
|
964
|
|
|
|
|
|
|
it will return the equivalent Perl data structure. |
|
965
|
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
Returns the Perl data structure on success or C on failure. |
|
967
|
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
=head2 C |
|
969
|
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
my $ret = perl2dump($perlvar, $optional_paramshashref) |
|
971
|
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
Arguments: |
|
973
|
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
=over 4 |
|
975
|
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
=item * C<$perlvar> |
|
977
|
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
=item * C<$optional_paramshashref> |
|
979
|
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
=back |
|
981
|
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
Return value: |
|
983
|
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
=over 4 |
|
985
|
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
=item * C<$ret> |
|
987
|
|
|
|
|
|
|
|
|
988
|
|
|
|
|
|
|
=back |
|
989
|
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
Given an input C<$perlvar> (which can be a simple scalar or |
|
991
|
|
|
|
|
|
|
a nested data structure, but not an object), it will return |
|
992
|
|
|
|
|
|
|
the equivalent string (via L). |
|
993
|
|
|
|
|
|
|
In C<$optional_paramshashref> |
|
994
|
|
|
|
|
|
|
one can specify whether to escape unicode with |
|
995
|
|
|
|
|
|
|
C<< 'dont-bloody-escape-unicode' => 0 >>, |
|
996
|
|
|
|
|
|
|
(or C<< 'escape-unicode' => 1 >>). The DEFAULT |
|
997
|
|
|
|
|
|
|
behaviour is to NOT ESCAPE unicode. |
|
998
|
|
|
|
|
|
|
|
|
999
|
|
|
|
|
|
|
Additionally, use terse output with C<< 'terse' => 1 >> and remove |
|
1000
|
|
|
|
|
|
|
all the incessant indentation with C<< 'indent' => 1 >> |
|
1001
|
|
|
|
|
|
|
which unfortunately goes to the other extreme of |
|
1002
|
|
|
|
|
|
|
producing a space-less output, not fit for human consumption. |
|
1003
|
|
|
|
|
|
|
The output can be fed to L |
|
1004
|
|
|
|
|
|
|
for getting the Perl variable back. |
|
1005
|
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
It returns the string representation of the input perl variable |
|
1007
|
|
|
|
|
|
|
on success or C on failure. |
|
1008
|
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
The output can be fed back to L. |
|
1010
|
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
CAVEAT: when not escaping unicode (which is the default |
|
1012
|
|
|
|
|
|
|
behaviour), each call to this sub will override L's |
|
1013
|
|
|
|
|
|
|
C sub then |
|
1014
|
|
|
|
|
|
|
call L's C and save its output to |
|
1015
|
|
|
|
|
|
|
a temporary variable, restore C sub to its original |
|
1016
|
|
|
|
|
|
|
code ref and return the |
|
1017
|
|
|
|
|
|
|
contents. This exercise is done every time this C |
|
1018
|
|
|
|
|
|
|
is called. It may be expensive. The alternative is |
|
1019
|
|
|
|
|
|
|
to redefine C once, when the module is loaded, with |
|
1020
|
|
|
|
|
|
|
all the side-effects this may cause. |
|
1021
|
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
Note that there are two other alternative subs which offer more-or-less |
|
1023
|
|
|
|
|
|
|
the same functionality and their output can be fed back to all the C<< dump2*() >> |
|
1024
|
|
|
|
|
|
|
subs. These are |
|
1025
|
|
|
|
|
|
|
L which uses L |
|
1026
|
|
|
|
|
|
|
to add a filter to control unicode escaping but |
|
1027
|
|
|
|
|
|
|
lacks in aesthetics and functionality and handling all the |
|
1028
|
|
|
|
|
|
|
cases Dump and Dumper do quite well. |
|
1029
|
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
There is also C<< perl2dump_homebrew() >> which |
|
1031
|
|
|
|
|
|
|
uses the same dump-recursively engine as |
|
1032
|
|
|
|
|
|
|
L |
|
1033
|
|
|
|
|
|
|
but does not involve Data::Dump at all. |
|
1034
|
|
|
|
|
|
|
|
|
1035
|
|
|
|
|
|
|
=head2 C |
|
1036
|
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
my $ret = perl2dump_filtered($perlvar, $optional_paramshashref) |
|
1038
|
|
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
Arguments: |
|
1040
|
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
=over 4 |
|
1042
|
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
=item * C<$perlvar> |
|
1044
|
|
|
|
|
|
|
|
|
1045
|
|
|
|
|
|
|
=item * C<$optional_paramshashref> |
|
1046
|
|
|
|
|
|
|
|
|
1047
|
|
|
|
|
|
|
=back |
|
1048
|
|
|
|
|
|
|
|
|
1049
|
|
|
|
|
|
|
Return value: |
|
1050
|
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
=over 4 |
|
1052
|
|
|
|
|
|
|
|
|
1053
|
|
|
|
|
|
|
=item * C<$ret> |
|
1054
|
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
=back |
|
1056
|
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
It does the same job as L which is |
|
1058
|
|
|
|
|
|
|
to stringify a perl variable. And takes the same options. |
|
1059
|
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
It returns the string representation of the input perl variable |
|
1061
|
|
|
|
|
|
|
on success or C on failure. |
|
1062
|
|
|
|
|
|
|
|
|
1063
|
|
|
|
|
|
|
It uses L to add a filter to |
|
1064
|
|
|
|
|
|
|
L. |
|
1065
|
|
|
|
|
|
|
|
|
1066
|
|
|
|
|
|
|
|
|
1067
|
|
|
|
|
|
|
=head2 C |
|
1068
|
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
my $ret = perl2dump_homebrew($perlvar, $optional_paramshashref) |
|
1070
|
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
Arguments: |
|
1072
|
|
|
|
|
|
|
|
|
1073
|
|
|
|
|
|
|
=over 4 |
|
1074
|
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
=item * C<$perlvar> |
|
1076
|
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
=item * C<$optional_paramshashref> |
|
1078
|
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
=back |
|
1080
|
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
Return value: |
|
1082
|
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
=over 4 |
|
1084
|
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
=item * C<$ret> |
|
1086
|
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
=back |
|
1088
|
|
|
|
|
|
|
|
|
1089
|
|
|
|
|
|
|
It does the same job as L which is |
|
1090
|
|
|
|
|
|
|
to stringify a perl variable. And takes the same options. |
|
1091
|
|
|
|
|
|
|
|
|
1092
|
|
|
|
|
|
|
It returns the string representation of the input perl variable |
|
1093
|
|
|
|
|
|
|
on success or C on failure. |
|
1094
|
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
The output can be fed back to L. |
|
1096
|
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
It uses its own basic dumper. Which is recursive. |
|
1098
|
|
|
|
|
|
|
So, beware of extremely deep nested data structures. |
|
1099
|
|
|
|
|
|
|
Deep not long! But it probably is as efficient as |
|
1100
|
|
|
|
|
|
|
it can be but definetely lacks in aesthetics |
|
1101
|
|
|
|
|
|
|
and functionality compared to Dump and Dumper. |
|
1102
|
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
=head2 C |
|
1104
|
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
my $ret = dump_perl_var_recursively($perl_var) |
|
1106
|
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
Arguments: |
|
1108
|
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
=over 4 |
|
1110
|
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
=item * C<$perl_var>, a Perl variable like |
|
1112
|
|
|
|
|
|
|
a scalar or an arbitrarily nested data structure. |
|
1113
|
|
|
|
|
|
|
For the latter, it requires references, e.g. |
|
1114
|
|
|
|
|
|
|
hash-ref or arrayref. |
|
1115
|
|
|
|
|
|
|
|
|
1116
|
|
|
|
|
|
|
=back |
|
1117
|
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
Return value: |
|
1119
|
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
=over 4 |
|
1121
|
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
=item * C<$ret>, the stringified version of the input Perl variable. |
|
1123
|
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
=back |
|
1125
|
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
This sub will take a Perl var (as a scalar or an arbitrarily nested data structure) |
|
1127
|
|
|
|
|
|
|
and emulate a very very basic |
|
1128
|
|
|
|
|
|
|
Dump/Dumper but with enforced rendering unicode (for keys or values or array items), |
|
1129
|
|
|
|
|
|
|
and not escaping unicode - this is not an option, |
|
1130
|
|
|
|
|
|
|
it returns a string representation of the input perl var |
|
1131
|
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
There are 2 obvious limitations: |
|
1133
|
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
=over 4 |
|
1135
|
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
=item 1. indentation is very basic, |
|
1137
|
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
=item 2. it supports only scalars, hashes and arrays, |
|
1139
|
|
|
|
|
|
|
(which will dive into them no problem) |
|
1140
|
|
|
|
|
|
|
This sub can be used in conjuction with DataDumpFilterino() |
|
1141
|
|
|
|
|
|
|
to create a Data::Dump filter like, |
|
1142
|
|
|
|
|
|
|
|
|
1143
|
|
|
|
|
|
|
Data::Dump::Filtered::add_dump_filter( \& DataDumpFilterino ); |
|
1144
|
|
|
|
|
|
|
or |
|
1145
|
|
|
|
|
|
|
dumpf($perl_var, \& DataDumpFilterino); |
|
1146
|
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
the input is a Perl variable as a reference, so no C<< %inp >> but C<< $inp={} >> |
|
1148
|
|
|
|
|
|
|
and C<< $inp=[] >>. |
|
1149
|
|
|
|
|
|
|
|
|
1150
|
|
|
|
|
|
|
This function is recursive. |
|
1151
|
|
|
|
|
|
|
Beware of extremely deep nested data structures. |
|
1152
|
|
|
|
|
|
|
Deep not long! But it probably is as efficient as |
|
1153
|
|
|
|
|
|
|
it can be but definetely lacks in aesthetics |
|
1154
|
|
|
|
|
|
|
and functionality compared to Dump and Dumper. |
|
1155
|
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
The output is a, possibly multiline, string. Which it can |
|
1157
|
|
|
|
|
|
|
then be fed back to L. |
|
1158
|
|
|
|
|
|
|
|
|
1159
|
|
|
|
|
|
|
=back |
|
1160
|
|
|
|
|
|
|
|
|
1161
|
|
|
|
|
|
|
=head2 C |
|
1162
|
|
|
|
|
|
|
# CAVEAT: it will eval($dumpstring) internally, so |
|
1163
|
|
|
|
|
|
|
# check $dumpstring for malicious code beforehand |
|
1164
|
|
|
|
|
|
|
# it is a security risk if you don't. |
|
1165
|
|
|
|
|
|
|
# Don't use it if $dumpstring comes from |
|
1166
|
|
|
|
|
|
|
# untrusted sources (user input for example). |
|
1167
|
|
|
|
|
|
|
my $ret = dump2perl($dumpstring) |
|
1168
|
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
Arguments: |
|
1170
|
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
=over 4 |
|
1172
|
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
=item * C<$dumpstring>, this comes from the output of L, |
|
1174
|
|
|
|
|
|
|
L or our own L, |
|
1175
|
|
|
|
|
|
|
L, |
|
1176
|
|
|
|
|
|
|
L. |
|
1177
|
|
|
|
|
|
|
Escaped, or unescaped. |
|
1178
|
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
=back |
|
1180
|
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
Return value: |
|
1182
|
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
=over 4 |
|
1184
|
|
|
|
|
|
|
|
|
1185
|
|
|
|
|
|
|
=item * C<$ret>, the Perl data structure on success or C on failure. |
|
1186
|
|
|
|
|
|
|
|
|
1187
|
|
|
|
|
|
|
=back |
|
1188
|
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
CAVEAT: it B's the input C<$dumpstring> in order to create the Perl data structure. |
|
1190
|
|
|
|
|
|
|
B'ing unknown or unchecked input is a security risk. Always check input to B |
|
1191
|
|
|
|
|
|
|
which comes from untrusted sources, like user input, scraped documents, email content. |
|
1192
|
|
|
|
|
|
|
Anything really. |
|
1193
|
|
|
|
|
|
|
|
|
1194
|
|
|
|
|
|
|
=head2 C |
|
1195
|
|
|
|
|
|
|
|
|
1196
|
|
|
|
|
|
|
my $ret = json2perl($jsonstring) |
|
1197
|
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
Arguments: |
|
1199
|
|
|
|
|
|
|
|
|
1200
|
|
|
|
|
|
|
=over 4 |
|
1201
|
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
=item * C<$jsonstring> |
|
1203
|
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
=back |
|
1205
|
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
Return value: |
|
1207
|
|
|
|
|
|
|
|
|
1208
|
|
|
|
|
|
|
=over 4 |
|
1209
|
|
|
|
|
|
|
|
|
1210
|
|
|
|
|
|
|
=item * C<$ret> |
|
1211
|
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
=back |
|
1213
|
|
|
|
|
|
|
|
|
1214
|
|
|
|
|
|
|
Given an input C<$jsonstring> as a string, it will return |
|
1215
|
|
|
|
|
|
|
the equivalent Perl data structure using |
|
1216
|
|
|
|
|
|
|
C. |
|
1217
|
|
|
|
|
|
|
|
|
1218
|
|
|
|
|
|
|
Returns the Perl data structure on success or C on failure. |
|
1219
|
|
|
|
|
|
|
|
|
1220
|
|
|
|
|
|
|
=head2 C |
|
1221
|
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
my $ret = jsonfile2perl($filename) |
|
1223
|
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
Arguments: |
|
1225
|
|
|
|
|
|
|
|
|
1226
|
|
|
|
|
|
|
=over 4 |
|
1227
|
|
|
|
|
|
|
|
|
1228
|
|
|
|
|
|
|
=item * C<$filename> |
|
1229
|
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
=back |
|
1231
|
|
|
|
|
|
|
|
|
1232
|
|
|
|
|
|
|
Return value: |
|
1233
|
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
=over 4 |
|
1235
|
|
|
|
|
|
|
|
|
1236
|
|
|
|
|
|
|
=item * C<$ret> |
|
1237
|
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
=back |
|
1239
|
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
Given an input C<$filename> which points to a file containing JSON content, |
|
1241
|
|
|
|
|
|
|
it will return the equivalent Perl data structure. |
|
1242
|
|
|
|
|
|
|
|
|
1243
|
|
|
|
|
|
|
Returns the Perl data structure on success or C on failure. |
|
1244
|
|
|
|
|
|
|
|
|
1245
|
|
|
|
|
|
|
=head2 C |
|
1246
|
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
my $ret = json2yaml($jsonstring, $optional_paramshashref) |
|
1248
|
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
Arguments: |
|
1250
|
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
=over 4 |
|
1252
|
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
=item * C<$jsonstring> |
|
1254
|
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
=item * C<$optional_paramshashref> |
|
1256
|
|
|
|
|
|
|
|
|
1257
|
|
|
|
|
|
|
=back |
|
1258
|
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
Return value: |
|
1260
|
|
|
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
=over 4 |
|
1262
|
|
|
|
|
|
|
|
|
1263
|
|
|
|
|
|
|
=item * C<$ret> |
|
1264
|
|
|
|
|
|
|
|
|
1265
|
|
|
|
|
|
|
=back |
|
1266
|
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
Given an input JSON string C<$jsonstring>, it will return |
|
1268
|
|
|
|
|
|
|
the equivalent YAML string L |
|
1269
|
|
|
|
|
|
|
by first converting JSON to a Perl variable and then |
|
1270
|
|
|
|
|
|
|
converting that variable to YAML using L. |
|
1271
|
|
|
|
|
|
|
All the parameters supported by L |
|
1272
|
|
|
|
|
|
|
are accepted. |
|
1273
|
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
Returns the YAML string on success or C on failure. |
|
1275
|
|
|
|
|
|
|
|
|
1276
|
|
|
|
|
|
|
=head2 C |
|
1277
|
|
|
|
|
|
|
|
|
1278
|
|
|
|
|
|
|
my $ret = yaml2json($yamlstring, $optional_paramshashref) |
|
1279
|
|
|
|
|
|
|
|
|
1280
|
|
|
|
|
|
|
Arguments: |
|
1281
|
|
|
|
|
|
|
|
|
1282
|
|
|
|
|
|
|
=over 4 |
|
1283
|
|
|
|
|
|
|
|
|
1284
|
|
|
|
|
|
|
=item * C<$yamlstring> |
|
1285
|
|
|
|
|
|
|
|
|
1286
|
|
|
|
|
|
|
=item * C<$optional_paramshashref> |
|
1287
|
|
|
|
|
|
|
|
|
1288
|
|
|
|
|
|
|
=back |
|
1289
|
|
|
|
|
|
|
|
|
1290
|
|
|
|
|
|
|
Return value: |
|
1291
|
|
|
|
|
|
|
|
|
1292
|
|
|
|
|
|
|
=over 4 |
|
1293
|
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
=item * C<$ret> |
|
1295
|
|
|
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
=back |
|
1297
|
|
|
|
|
|
|
|
|
1298
|
|
|
|
|
|
|
Given an input YAML string C<$yamlstring>, it will return |
|
1299
|
|
|
|
|
|
|
the equivalent YAML string L |
|
1300
|
|
|
|
|
|
|
by first converting YAML to a Perl variable and then |
|
1301
|
|
|
|
|
|
|
converting that variable to JSON using L. |
|
1302
|
|
|
|
|
|
|
All the parameters supported by L |
|
1303
|
|
|
|
|
|
|
are accepted. |
|
1304
|
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
Returns the JSON string on success or C on failure. |
|
1306
|
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
=head2 C C |
|
1308
|
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
Transform a json or yaml string via pretty printing or via |
|
1310
|
|
|
|
|
|
|
escaping unicode or via un-escaping unicode. Parameters |
|
1311
|
|
|
|
|
|
|
like above will be accepted. |
|
1312
|
|
|
|
|
|
|
|
|
1313
|
|
|
|
|
|
|
=head2 C C C C |
|
1314
|
|
|
|
|
|
|
|
|
1315
|
|
|
|
|
|
|
similar functionality as their counterparts described above. |
|
1316
|
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
=head2 C |
|
1318
|
|
|
|
|
|
|
|
|
1319
|
|
|
|
|
|
|
my $contents = read_from_file($filename) |
|
1320
|
|
|
|
|
|
|
|
|
1321
|
|
|
|
|
|
|
Arguments: |
|
1322
|
|
|
|
|
|
|
|
|
1323
|
|
|
|
|
|
|
=over 4 |
|
1324
|
|
|
|
|
|
|
|
|
1325
|
|
|
|
|
|
|
=item * C<$filename> : the input filename. |
|
1326
|
|
|
|
|
|
|
|
|
1327
|
|
|
|
|
|
|
=back |
|
1328
|
|
|
|
|
|
|
|
|
1329
|
|
|
|
|
|
|
Return value: |
|
1330
|
|
|
|
|
|
|
|
|
1331
|
|
|
|
|
|
|
=over 4 |
|
1332
|
|
|
|
|
|
|
|
|
1333
|
|
|
|
|
|
|
=item * C<$contents> |
|
1334
|
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
=back |
|
1336
|
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
Given a filename, it opens it using C<< :encoding(UTF-8) >>, slurps its |
|
1338
|
|
|
|
|
|
|
contents and closes it. It's a convenience sub which could have also |
|
1339
|
|
|
|
|
|
|
been private. If you want to retain the filehandle, use |
|
1340
|
|
|
|
|
|
|
L. |
|
1341
|
|
|
|
|
|
|
|
|
1342
|
|
|
|
|
|
|
Returns the file contents on success or C on failure. |
|
1343
|
|
|
|
|
|
|
|
|
1344
|
|
|
|
|
|
|
=head2 C |
|
1345
|
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
my $contents = read_from_filehandle($filehandle) |
|
1347
|
|
|
|
|
|
|
|
|
1348
|
|
|
|
|
|
|
Arguments: |
|
1349
|
|
|
|
|
|
|
|
|
1350
|
|
|
|
|
|
|
=over 4 |
|
1351
|
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
=item * C<$filehandle> : the handle to an already opened file. |
|
1353
|
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
=back |
|
1355
|
|
|
|
|
|
|
|
|
1356
|
|
|
|
|
|
|
Return value: |
|
1357
|
|
|
|
|
|
|
|
|
1358
|
|
|
|
|
|
|
=over 4 |
|
1359
|
|
|
|
|
|
|
|
|
1360
|
|
|
|
|
|
|
=item * C<$contents> : the file contents slurped. |
|
1361
|
|
|
|
|
|
|
|
|
1362
|
|
|
|
|
|
|
=back |
|
1363
|
|
|
|
|
|
|
|
|
1364
|
|
|
|
|
|
|
It slurps all content from the specified input file handle. Upon return |
|
1365
|
|
|
|
|
|
|
the file handle is still open. |
|
1366
|
|
|
|
|
|
|
Returns the file contents on success or C on failure. |
|
1367
|
|
|
|
|
|
|
|
|
1368
|
|
|
|
|
|
|
=head2 C |
|
1369
|
|
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
write_to_file($filename, $contents) or die |
|
1371
|
|
|
|
|
|
|
|
|
1372
|
|
|
|
|
|
|
Arguments: |
|
1373
|
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
=over 4 |
|
1375
|
|
|
|
|
|
|
|
|
1376
|
|
|
|
|
|
|
=item * C<$filename> : the output filename. |
|
1377
|
|
|
|
|
|
|
|
|
1378
|
|
|
|
|
|
|
=item * C<$contents> : any string to write it to file. |
|
1379
|
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
=back |
|
1381
|
|
|
|
|
|
|
|
|
1382
|
|
|
|
|
|
|
Return value: |
|
1383
|
|
|
|
|
|
|
|
|
1384
|
|
|
|
|
|
|
=over 4 |
|
1385
|
|
|
|
|
|
|
|
|
1386
|
|
|
|
|
|
|
=item * 1 on success, 0 on failure |
|
1387
|
|
|
|
|
|
|
|
|
1388
|
|
|
|
|
|
|
=back |
|
1389
|
|
|
|
|
|
|
|
|
1390
|
|
|
|
|
|
|
Given a filename, it opens it using C<< :encoding(UTF-8) >>, |
|
1391
|
|
|
|
|
|
|
writes all specified content and closes the file. |
|
1392
|
|
|
|
|
|
|
It's a convenience sub which could have also |
|
1393
|
|
|
|
|
|
|
been private. If you want to retain the filehandle, use |
|
1394
|
|
|
|
|
|
|
L. |
|
1395
|
|
|
|
|
|
|
|
|
1396
|
|
|
|
|
|
|
Returns 1 on success or 0 on failure. |
|
1397
|
|
|
|
|
|
|
|
|
1398
|
|
|
|
|
|
|
=head2 C |
|
1399
|
|
|
|
|
|
|
|
|
1400
|
|
|
|
|
|
|
write_to_filehandle($filehandle, $contents) or die |
|
1401
|
|
|
|
|
|
|
|
|
1402
|
|
|
|
|
|
|
Arguments: |
|
1403
|
|
|
|
|
|
|
|
|
1404
|
|
|
|
|
|
|
=over 4 |
|
1405
|
|
|
|
|
|
|
|
|
1406
|
|
|
|
|
|
|
=item * C<$filehandle> : the handle to an already opened file (for writing). |
|
1407
|
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
=back |
|
1409
|
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
Return value: |
|
1411
|
|
|
|
|
|
|
|
|
1412
|
|
|
|
|
|
|
=over 4 |
|
1413
|
|
|
|
|
|
|
|
|
1414
|
|
|
|
|
|
|
=item * 1 on success or 0 on failure. |
|
1415
|
|
|
|
|
|
|
|
|
1416
|
|
|
|
|
|
|
=back |
|
1417
|
|
|
|
|
|
|
|
|
1418
|
|
|
|
|
|
|
It writes content to the specified file handle. Upon return |
|
1419
|
|
|
|
|
|
|
the file handle is still open. |
|
1420
|
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
Returns 1 on success or 0 on failure. |
|
1422
|
|
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
=head1 SCRIPTS |
|
1424
|
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
A few scripts have been put together and offer the functionality of this |
|
1426
|
|
|
|
|
|
|
module to the command line. They are part of this distribution and can |
|
1427
|
|
|
|
|
|
|
be found in the C |