NAME
Data::Roundtrip - convert between Perl data structures, YAML and JSON with unicode support (I believe ...)
VERSION
Version 0.06
SYNOPSIS
This module contains a collection of utilities for converting between JSON, YAML, Perl variable and a Perl variable's string representation (aka dump). Hopefully, all unicode content will be handled correctly between the conversions and optionally escaped or un-escaped. Also JSON can be presented in a pretty format or in a condensed, machine-readable format (not spaces, indendation or line breaks).
use Data::Roundtrip qw/:all/;
$jsonstr = '{"Songname": "Απόκληρος της κοινωνίας",'
.'"Artist": "Καζαντζίδης Στέλιος/Βίρβος Κώστας"}'
;
$yamlstr = json2yaml($jsonstr);
print $yamlstr;
# NOTE: long strings have been broken into multilines
# and/or truncated (replaced with ...)
#---
#Artist: Καζαντζίδης Στέλιος/Βίρβος Κώστας
#Songname: Απόκληρος της κοινωνίας
$yamlstr = json2yaml($jsonstr, {'escape-unicode'=>1});
print $yamlstr;
#---
#Artist: \u039a\u03b1\u03b6\u03b1 ...
#Songname: \u0391\u03c0\u03cc\u03ba ...
$backtojson = yaml2json($yamlstr);
# $backtojson is a string representation
# of following JSON structure:
# {"Artist":"Καζαντζίδης Στέλιος/Βίρβος Κώστας",
# "Songname":"Απόκληρος της κοινωνίας"}
# This is useful when sending JSON via
# a POST request and it needs unicode escaped:
$backtojson = yaml2json($yamlstr, {'escape-unicode'=>1});
# $backtojson is a string representation
# of following JSON structure:
# but this time with unicode escaped
# (pod content truncated for readbility)
# {"Artist":"\u039a\u03b1\u03b6 ...",
# "Songname":"\u0391\u03c0\u03cc ..."}
# this is the usual Data::Dumper dump:
print json2dump($jsonstr);
#$VAR1 = {
# 'Songname' => "\x{391}\x{3c0}\x{3cc} ...",
# 'Artist' => "\x{39a}\x{3b1}\x{3b6} ...",
#};
# and this is a more human-readable version:
print json2dump($jsonstr, {'dont-bloody-escape-unicode'=>1});
# $VAR1 = {
# "Artist" => "Καζαντζίδης Στέλιος/Βίρβος Κώστας",
# "Songname" => "Απόκληρος της κοινωνίας"
# };
# pass some parameters to Data::Dumper
# like: be terse (no $VAR1):
print json2dump($jsonstr,
{'dont-bloody-escape-unicode'=>0, 'terse'=>1}
#{'dont-bloody-escape-unicode'=>0, 'terse'=>1, 'indent'=>0}
);
# {
# "Artist" => "Καζαντζίδης Στέλιος/Βίρβος Κώστας",
# "Songname" => "Απόκληρος της κοινωνίας"
# }
# this is how to reformat a JSON string to
# have its unicode content escaped:
my $json_with_unicode_escaped =
json2json($jsonstr, {'escape-unicode'=>1});
# For some of the above functions there exist command-line scripts:
perl2json.pl -i "perl-data-structure.pl" -o "output.json" --pretty
json2json.pl -i "with-unicode.json" -o "unicode-escaped.json" --escape-unicode
# etc.
EXPORT
By default no symbols are exported. However, the following export tags are available (:all will export all of them):
:json:perl2json(),json2perl(),json2dump(),json2yaml(),json2json():yaml:perl2yaml(),yaml2perl(),yaml2dump(),yaml2yaml(),yaml2json():dump:perl2dump(),dump2perl(),dump2json(),dump2yaml():io:read_from_file(),write_to_file(),read_from_filehandle(),write_to_filehandle(),:all: everything above
SUBROUTINES
perl2json
my $ret = perl2json($perlvar, $optional_paramshashref)
Arguments:
$perlvar$optional_paramshashref
Return value:
$ret
Given an input $perlvar (which can be a simple scalar or
a nested data structure, but not an object), it will return
the equivalent JSON string. In $optional_paramshashref
one can specify whether to escape unicode with
'escape-unicode' => 1
and/or prettify the returned result with 'pretty' => 1.
The output can be fed back to Data::Roundtrip's json2perl()
for getting the Perl variable back.
Returns the JSON string on success or undef on failure.
json2perl
Arguments:
$jsonstring
Return value:
$ret
Given an input $jsonstring as a string, it will return
the equivalent Perl data structure using
JSON::decode_json(Encode::encode_utf8($jsonstring)).
Returns the Perl data structure on success or undef on failure.
perl2yaml
my $ret = perl2yaml($perlvar, $optional_paramshashref)
Arguments:
$perlvar$optional_paramshashref
Return value:
$ret
Given an input $perlvar (which can be a simple scalar or
a nested data structure, but not an object), it will return
the equivalent YAML string. In $optional_paramshashref
one can specify whether to escape unicode with
'escape-unicode' => 1. Prettify is not supported yet.
The output can fed to Data::Roundtrip's yaml2perl()
for getting the Perl variable back.
Returns the YAML string on success or undef on failure.
yaml2perl
my $ret = yaml2perl($yamlstring);
Arguments:
$yamlstring
Return value:
$ret
Given an input $yamlstring as a string, it will return
the equivalent Perl data structure using
YAML::Load($yamlstring)
Returns the Perl data structure on success or undef on failure.
perl2dump
my $ret = perl2dump($perlvar, $optional_paramshashref)
Arguments:
$perlvar$optional_paramshashref
Return value:
$ret
Given an input $perlvar (which can be a simple scalar or
a nested data structure, but not an object), it will return
the equivalent string (via Data::Dumper).
In $optional_paramshashref
one can specify whether to escape unicode with
'dont-bloody-escape-unicode' => 0,
(or 'escape-unicode' => 1). The DEFAULT
behaviour is to NOT ESCAPE unicode.
Additionally, use terse output with 'terse' => 1 and remove
all the incessant indentation with 'indent' => 1
which unfortunately goes to the other extreme of
producing a space-less output, not fit for human consumption.
The output can fed to Data::Roundtrip's dump2perl()
for getting the Perl variable back.
It returns the string representation of the input perl variable
on success or undef on failure.
The output can be fed back to Data::Roundtrip's dump2perl().
CAVEAT: when not escaping unicode (which is the default
behaviour), each call to this sub will override Data::Dumper's
qquote() sub (with a call to Sub::Override' new()),
call Data::Dumper's Dumper() and save its output to
a temporary variable, restore qquote() sub (with
a call to Sub::Override's restore() and return the
contents. This exercise is done every time this perl2dump()
is called. It can be expensive. The alternative is
to redefine qquote() once, when the module is loaded.
Note that there are two other alternatives to this sub,
Data::Roundtrip's perl2dump_filtered() which uses Data::Dump
filters to control unicode escaping but
lacks in aesthetics and functionality and handling all the
cases Dump and Dumper do quite well.
There is also perl2dump_homebrew() which
uses the same dump-recursively engine as
Data::Roundtrip's perl2dump_filtered()
but does not involve Data::Dump at all.
perl2dump_filtered
my $ret = perl2dump_filtered($perlvar, $optional_paramshashref)
Arguments:
$perlvar$optional_paramshashref
Return value:
$ret
It does the same job as Data::Roundtrip's perl2dump() which is
to stringify a perl variable. And takes the same options.
It returns the string representation of the input perl variable
on success or undef on failure.
It uses Data::Dump::Filtered to add a filter to Data::Dump.
perl2dump_homebrew
my $ret = perl2dump_homebrew($perlvar, $optional_paramshashref)
Arguments:
$perlvar$optional_paramshashref
Return value:
$ret
It does the same job as Data::Roundtrip's perl2dump() which is
to stringify a perl variable. And takes the same options.
It returns the string representation of the input perl variable
on success or undef on failure.
The output can be fed back to Data::Roundtrip's dump2perl().
It uses its own basic dumper. Which is recursive. So, beware of extremely deep nested data structures. Deep not long! But it probably is as efficient as it can be but definetely lacks in aesthetics and functionality compared to Dump and Dumper.
dump_perl_var_recursively
my $ret = dump_perl_var_recursively($perl_var)
Arguments:
$perl_var, a Perl variable like a scalar or an arbitrarily nested data structure. For the latter, it requires references, e.g. hash-ref or arrayref.
Return value:
$ret, the stringified version of the input Perl variable.
This sub will take a Perl var (as a scalar or an arbitrarily nested data structure) and emulate a very very basic Dump/Dumper but with enforced rendering unicode (for keys or values or array items), and not escaping unicode - this is not an option, it returns a string representation of the input perl var
There are 2 obvious limitations:
-
- indentation is very basic,
-
-
it supports only scalars, hashes and arrays, (which will dive into them no problem) This sub can be used in conjuction with DataDumpFilterino() to create a Data::Dump filter like,
Data::Dump::Filtered::add_dump_filter( \& DataDumpFilterino );
or dumpf($perl_var, & DataDumpFilterino);
the input is a Perl variable as a reference, so no
%inpbut$inp={}and$inp=[].This function is recursive. Beware of extremely deep nested data structures. Deep not long! But it probably is as efficient as it can be but definetely lacks in aesthetics and functionality compared to Dump and Dumper.
The output is a, possibly multiline, string. Which it can then be fed back to Data::Roundtrip's
dump2perl(). -
dump2perl
my $ret = dump2perl($dumpstring)
Arguments:
$dumpstring, this comes from the output of Data::Dump, Data::Dumper or our own Data::Roundtrip'sperl2dump(), Data::Roundtrip'sperl2dump_filtered(), Data::Roundtrip'sperl2dump_homebrew(). Escaped, or unescaped.
Return value:
$ret, the Perl data structure on success orundefon failure.
json2perl
my $ret = json2perl($jsonstring)
Arguments:
$jsonstring
Return value:
$ret
Given an input $jsonstring as a string, it will return
the equivalent Perl data structure using
JSON::decode_json(Encode::encode_utf8($jsonstring)).
Returns the Perl data structure on success or undef on failure.
In $optional_paramshashref
one can specify whether to escape unicode with
'escape-unicode' => 1
and/or prettify the returned result with 'pretty' => 1.
Returns the yaml string on success or undef on failure.
json2yaml
my $ret = json2yaml($jsonstring, $optional_paramshashref)
Arguments:
$jsonstring$optional_paramshashref
Return value:
$ret
Given an input JSON string $jsonstring, it will return
the equivalent YAML string YAML
by first converting JSON to a Perl variable and then
converting that variable to YAML using Data::Roundtrip's perl2yaml().
All the parameters supported by Data::Roundtrip's perl2yaml()
are accepted.
Returns the YAML string on success or undef on failure.
yaml2json
my $ret = yaml2json($yamlstring, $optional_paramshashref)
Arguments:
$yamlstring$optional_paramshashref
Return value:
$ret
Given an input YAML string $yamlstring, it will return
the equivalent YAML string YAML
by first converting YAML to a Perl variable and then
converting that variable to JSON using Data::Roundtrip's perl2json().
All the parameters supported by Data::Roundtrip's perl2json()
are accepted.
Returns the JSON string on success or undef on failure.
json2json yaml2yaml
Transform a json or yaml string via pretty printing or via escaping unicode or via un-escaping unicode. Parameters like above will be accepted.
json2dump dump2json yaml2dump dump2yaml
similar functionality as their counterparts described above.
read_from_file
my $contents = read_from_file($filename)
Arguments:
$filename: the input filename.
Return value:
$contents
Given a filename, it opens it using :encoding(UTF-8), slurps its
contents and closes it. It's a convenience sub which could have also
been private. If you want to retain the filehandle, use
Data::Roundtrip's read_from_filehandle().
Returns the file contents on success or undef on failure.
read_from_filehandle
my $contents = read_from_filehandle($filehandle)
Arguments:
$filehandle: the handle to an already opened file.
Return value:
$contents: the file contents slurped.
It slurps all content from the specified input file handle. Upon return
the file handle is still open.
Returns the file contents on success or undef on failure.
write_to_file
write_to_file($filename, $contents) or die
Arguments:
$filename: the output filename.$contents: any string to write it to file.
Return value:
- 1 on success, 0 on failure
Given a filename, it opens it using :encoding(UTF-8),
writes all specified content and closes the file.
It's a convenience sub which could have also
been private. If you want to retain the filehandle, use
Data::Roundtrip's write_to_filehandle().
Returns 1 on success or 0 on failure.
write_to_filehandle
write_to_filehandle($filehandle, $contents) or die
Arguments:
$filehandle: the handle to an already opened file (for writing).
Return value:
- 1 on success or 0 on failure.
It writes content to the specified file handle. Upon return the file handle is still open.
Returns 1 on success or 0 on failure.
SCRIPTS
A few scripts have been put together and offer the functionality of this
module to the command line. They are part of this distribution and can
be found in the script directory.
These are: json2json.pl, json2yaml.pl, yaml2json.pl,
json2perl.pl, perl2json.pl, yaml2perl.pl
AUTHOR
Andreas Hadjiprocopis, <bliako at cpan.org> / <andreashad2 at gmail.com>
BUGS
Please report any bugs or feature requests to bug-data-roundtrip at rt.cpan.org, or through
the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Data-Roundtrip. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
SEE ALSO
- Convert JSON to Perl and back with unicode
- RFC: Perl<->JSON<->YAML<->Dumper : roundtripping and possibly with unicode
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Data::Roundtrip
You can also look for information at:
-
RT: CPAN's request tracker (report bugs here)
-
AnnoCPAN: Annotated CPAN documentation
-
CPAN Ratings
-
Search CPAN
ACKNOWLEDGEMENTS
Several Monks at PerlMonks.org (in no particular order):
- haukex
- Corion (the
_qquote_redefinition_by_Corion()which harnesses Data::Dumper's incessant unicode escaping) - kcott (The EXPORT section among other suggestions)
- jwkrahn
- leszekdubiel
- marto
- and an anonymous monk
DEDICATIONS
Almaz!
LICENSE AND COPYRIGHT
This software, EXCEPT the portions created by [Corion] @ Perlmonks and [kcott] @ Perlmonks, is Copyright (c) 2020 by Andreas Hadjiprocopis.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)