Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Undumping Perl

by haukex (Bishop)
on Jul 03, 2016 at 18:27 UTC ( #1167085=CUFP: print w/replies, xml ) Need Help??

Respected Monks,

I'd like to present to you today, in hopes you might find it interesting or even useful, the result of scratching an itch I had for quite some time: parsing Perl data structures without eval; instead I do it with the great module PPI. The result is Config::Perl. A nice additional benefit is that the module can round-trip much of the output of Data::Dumper, for which I provide the helper module Data::Undump::PPI.

Let me demonstrate with code:

# --> This is an example configuration file, foo.conf $default_profile = 'alpha'; %profiles = ( 'alpha' => { path => '/etc/alpha', recurse => 1 }, 'beta' => { path => '/var/beta', recurse => 0 }, ); @resources = qw/ xyz abc def /;

Here's what it looks like when you read that file and display the resulting data structure:

use Config::Perl; my $parser = Config::Perl->new; my $conf = $parser->parse_or_die('foo.conf'); use Data::Dumper; print Dumper($conf);

Which outputs (whitespace edited for brevity):

$VAR1 = { '$default_profile' => 'alpha', '%profiles' => { 'alpha' => { 'path' => '/etc/alpha', 'recurse' => 1 }, 'beta' => { 'path' => '/var/beta', 'recurse' => 0 } }, '@resources' => [ 'xyz', 'abc', 'def' ] };

As you can see, Config::Perl returns a kind of "symbol table" for the parsed data structure.

Data::Undump::PPI makes round-tripping Perl data structures to and from strings (and files, see below) easier:

use Data::Dumper; $Data::Dumper::Purity=1; # setting these two options like this $Data::Dumper::Terse=0; # is important (see also "Dump" below) use Data::Undump::PPI; my @input = ( {foo=>"bar"}, ["Hello","World"], "undumping!" ); my $str = Dumper(@input); my @parsed = Undump($str);

In the above example, @parsed now looks identical to @input, and is essentially a deep copy. Another example:

Let's say you want to save some application state and restore it later - yesterday I released v0.06 which adds some helpful features, such as a helper for Data::Dumper called Dump (which sets up several Data::Dumper options) and the ability to read / write files directly:

use Data::Undump::PPI qw/Dump Undump/; Dump(\@state_out, file=>''); my @state_in = Undump(file=>'');

Having said all that, the modules are definitely not perfect (yet ;-)). There are of course many features of Perl that aren't supported (I'd end up re-implementing Perl otherwise), there's a list at the end of the Config::Perl documentation. As a result I currently often can't parse the output of, for example, Data::Dump, since that uses things like lexical variables or the range operator. Maybe I'll add support for those later.

Data::Undump::PPI seems to work fairly well as far as I can tell at the moment; the two notable things that aren't supported are deserializing objects (because Config::Perl doesn't support bless, although that might be possible in the future), and code references (for hopefully obvious reasons: without eval I'd have to re-implement Perl...).

So if you get a chance to play around with the modules, I'd be happy to hear your (constructive) feedback, bug reports, and so on :-)

-- Hauke D

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://1167085]
Approved by Corion
Front-paged by Arunbear
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2020-09-26 12:39 GMT
Find Nodes?
    Voting Booth?
    If at first I donít succeed, I Ö

    Results (141 votes). Check out past polls.