Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data::Dumper is hard to use reliably #3928

Closed
p5pRT opened this issue Apr 27, 2001 · 6 comments
Closed

Data::Dumper is hard to use reliably #3928

p5pRT opened this issue Apr 27, 2001 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 27, 2001

Migrated from rt.perl.org#6911 (status was 'resolved')

Searchable as RT6911$

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2001

From pimlott@idiomtech.com

Data​::Dumper is (needlessly?) difficult to use for serializing data
structures. Since this is probably a primary use of Data​::Dumper, it would
be nice to make it easier to do so reliably.

I'm referring mostly to the handling of self-referential data structures.
For starters, one must enable a non-default option (Purity) to handle them
at all. The only reason I can imagine for this is that the default output
is slightly more readable; but this seems a small gain in exchange for a
higher chance of data loss. Especially since code that doesn't set Purity
will likely work on (non-self-referential) test data, only to fail later.

Even with Purity, getting back the dumped data structure is gratuitously
tricky. If the data is self-referential, one must eval the dump, then get
the data from $VAR1. I can't imagine why the expression can't return $VAR1
directly. Further, all of the documentation examples use the result of the
eval. Again, this will work on test data, then fail later. If one makes
the mistake of setting Terse (the documentation has an example using Terse
and Purity together), it is even worse, because $VAR1 will not always be
available. There's also the matter of needing to turn off strict.

I guess the heart of the problem is that Data​::Dumper is used both for
pretty-printing (though I don't know why; I find Dumpvalue more readable)
and for serialization; but the documentation short-changes the latter. Some
examples​: "The contents of each variable is output in a single Perl
statement."--unless it is self-referential. "Handles self-referential
structures correctly."--vague. "The return value can be `eval'ed to get
back an identical copy of the original reference structure."--in general,
false. "Any references that are the same as one of those passed in will be
named `$VAR'n"--not true under terse.

Finally, there are no examples of how to use Data​::Dumper for reliable
serialization (or at least, as reliable as feasible, with caveats about
things like sub refs). This is what I do​:

  use Data​::Dumper;

  $dumper = new Data​::Dumper [ $data ];
  $dumped = $dumper->Purity(1)->Dump;
  ...
  {
  no strict 'vars';
  local $VAR1;
  eval $dumped;
  die "toast​: $@​" if $@​;
  $data = $VAR1;
  }

But I'm not 100% sure of it. I'm sure plenty of people have buggy code and
don't even know it.

What can be done? Is there any chance of changing the default behavior to
be less error-prone? If not, it would be nice if there were a section of
the documentation covering serialization, and if the misleading statements
in the introduction were clarified. I will be happy to write it, if someone
can assure me that I have a grasp on the issues. Of course, I will welcome
someone telling me I am way off base, as well.

Andrew

PS. It is also inconvenient and confusing that one cannot reuse a $dumper
object on multiple data structures.

Perl Info

Flags:
    category=library
    severity=wishlist

Site configuration information for perl v5.6.0:

Configured by bod at Fri Mar  9 06:08:27 EST 2001.

Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.4.2, archname=i386-linux
    uname='linux duende 2.4.2 #1 fri mar 2 13:52:32 est 2001 i686 unknown '
    config_args='-Dccflags=-DDEBIAN -Darchname=i386-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.6.0 -Darchlib=/usr/lib/perl/5.6.0 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.6.0 -Dsitearch=/usr/local/lib/perl/5.6.0 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/pager -Uafs -Ud_csh -Uusesfio -Duseshrplib -Dlibperl=libperl.so.5.6.0 -Dd_dosuid -des'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=undef d_sfio=undef uselargefiles=define 
    use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef
  Compiler:
    cc='cc', optimize='-O2', gccversion=2.95.3 20010219 (prerelease)
    cppflags='-DDEBIAN -fno-strict-aliasing -I/usr/local/include'
    ccflags ='-DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    stdchar='char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -ldl -lm -lc -lcrypt
    libc=/lib/libc-2.2.2.so, so=so, useshrplib=true, libperl=libperl.so.5.6.0
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.6.0:
    /home/pimlott/local/lib/perl5/i386-linux
    /home/pimlott/local/lib/perl5
    /usr/local/lib/perl/5.6.0
    /usr/local/share/perl/5.6.0
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.6.0
    /usr/share/perl/5.6.0
    /usr/local/lib/site_perl
    /usr/lib/perl5/5.6/i386-linux
    /usr/lib/perl5/5.6
    /usr/lib/perl5/5.005/i386-linux
    .


Environment for perl v5.6.0:
    HOME=/home/pimlott
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/pimlott/bin:/usr/local/atria/bin:/home/pimlott/local/jdk1.3/bin:/home/pimlott/local/j2sdkee1.2.1/bin:/usr/sbin:/sbin:/home/pimlott/bin:/usr/local/atria/bin:/home/pimlott/local/jdk1.3/bin:/home/pimlott/local/j2sdkee1.2.1/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
    PERL5LIB=/home/pimlott/local/lib/perl5
    PERL_BADLANG (unset)
    SHELL=/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2001

From [Unknown Contact. See original ticket]

[ ... deletia ... ]

There's also the matter of needing to turn off strict.

[ ... deletia ... ]

Finally, there are no examples of how to use Data​::Dumper for reliable
serialization (or at least, as reliable as feasible, with caveats about
things like sub refs). This is what I do​:

use Data​::Dumper;

$dumper = new Data​::Dumper \[ $data \];
$dumped = $dumper\->Purity\(1\)\->Dump;
\.\.\.
\{
    no strict 'vars';
    local $VAR1;
    eval $dumped;
    die "toast​: $@​" if $@​;
    $data = $VAR1;
\}

I won't address your comments about the difficulty of using
self-referential data, but the strictness can be addressed using the
two-argument form of new().

Serializing​:
  my $dumper = Data​::Dumper->new([ $data ], [ "data" ]);
  my $dumped = $dumper->Purity(1)->Dump;

Retrieving​:
  my $data;
  eval $dumped;
  die "toast​: $@​" if $@​;

And have you considered Storable?

Cheers,
-Ben

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2001

From [Unknown Contact. See original ticket]

Don't know why I didn't think of that :-)

And have you considered Storable?

Human-readability and eval-ability are both very nice features. I
would hate to give them up just because the API is difficult.

Andrew

@p5pRT
Copy link
Author

p5pRT commented Mar 29, 2012

From @jkeenan

On Fri Apr 27 01​:25​:19 2001, RT_System wrote​:

Don't know why I didn't think of that :-)

And have you considered Storable?

Human-readability and eval-ability are both very nice features. I
would hate to give them up just because the API is difficult.

Andrew

Andrew,

Are there specific errors with Data​::Dumper for which we need to keep
this RT open?

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Apr 30, 2012

From @jkeenan

On Wed Mar 28 19​:21​:36 2012, jkeenan wrote​:

On Fri Apr 27 01​:25​:19 2001, RT_System wrote​:

Don't know why I didn't think of that :-)

And have you considered Storable?

Human-readability and eval-ability are both very nice features. I
would hate to give them up just because the API is difficult.

Andrew

Andrew,

Are there specific errors with Data​::Dumper for which we need to keep
this RT open?

No further correspondence in the last month. Closing.

Thank you very much.
Jim Keenan

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Apr 30, 2012

@jkeenan - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant