Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[perl #28839] Data::Dumper mangles dualvars

0 views
Skip to first unread message

Zefram

unread,
Apr 15, 2004, 2:41:18 PM4/15/04
to bugs-bi...@netlabs.develooper.com
# New Ticket Created by Zefram
# Please include the string: [perl #28839]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org:80/rt3/Ticket/Display.html?id=28839 >

This is a bug report for perl from zef...@fysh.org,
generated with the help of perlbug 1.34 running under perl v5.8.3.


-----------------------------------------------------------------
[Please enter your report here]

I'm working with Data::Dumper version 2.121 for this bug report.

Data::Dumper, if given a dualvar (such as $!), only dumps the string
value. It ought to dump both values, in the form of a dualvar()
expression. Here's a patch that implements this in the Perl version of
the dump function:

--- /usr/lib/perl/5.8.3/Data/Dumper.pm 2004-03-27 06:52:27.000000000 +0000
+++ Dumper.pm 2004-04-15 19:22:43.000000000 +0100
@@ -449,17 +449,25 @@
elsif (!defined($val)) {
$out .= "undef";
}
- elsif ($val =~ /^(?:0|-?[1-9]\d{0,8})\z/) { # safe decimal number
- $out .= $val;
- }
- else { # string
+ else { # string/number
+ my $strval;
if ($s->{useqq} or $val =~ tr/\0-\377//c) {
# Fall back to qq if there's unicode
- $out .= qquote($val, $s->{useqq});
+ $strval = qquote($val, $s->{useqq});
}
else {
$val =~ s/([\\\'])/\\$1/g;
- $out .= '\'' . $val . '\'';
+ $strval = '\'' . $val . '\'';
+ }
+ no warnings "numeric";
+ if(0+$val eq $val) {
+ $out .= 0+$val;
+ }
+ elsif("$val" == $val) {
+ $out .= $strval;
+ }
+ else {
+ $out .= "dualvar(".(0+$val).", ".$strval.")";
}
}
}

I haven't tackled the C version. Example of old and new behaviour
(setting Useqq to force use of the Perl dump code):

$ perl -MData::Dumper -we '$Data::Dumper::Useqq=1; print Dumper($!)'
$VAR1 = "Bad file descriptor";
$ perl -I. -MData::Dumper -we '$Data::Dumper::Useqq=1; print Dumper($!)'
$VAR1 = dualvar(2, "No such file or directory");

Both before and after the patch, the code has a problem with floating
point numbers. It really needs a way to output the exact value
of a floating point number, whereas at the moment it uses builtin
stringification, which loses some digits. That's a separate issue that
just happens to be in the same chunk of code.

See also bug #28538 for the discussion of dualvars that led to this
bug report.

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=library
severity=medium
---
Site configuration information for perl v5.8.3:

Configured by Debian Project at Sat Mar 27 17:07:14 EST 2004.

Summary of my perl5 (revision 5.0 version 8 subversion 3) configuration:
Platform:
osname=linux, osvers=2.4.25-ti1211, archname=i386-linux-thread-multi
uname='linux kosh 2.4.25-ti1211 #1 thu feb 19 18:20:12 est 2004 i686 gnulinux '
config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i386-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.3 -Dsitearch=/usr/local/lib/perl/5.8.3 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.3 -Dd_dosuid -des'
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O3',
cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include'
ccversion='', gccversion='3.3.3 (Debian 20040314)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
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, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
perllibs=-ldl -lm -lpthread -lc -lcrypt
libc=/lib/libc-2.3.2.so, so=so, useshrplib=true, libperl=libperl.so.5.8.3
gnulibc_version='2.3.2'
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.8.3:
/etc/perl
/usr/local/lib/perl/5.8.3
/usr/local/share/perl/5.8.3
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.8
/usr/share/perl/5.8
/usr/local/lib/site_perl
.

---
Environment for perl v5.8.3:
HOME=/home/zefram
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/home/zefram/pub/i686-pc-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/local/bin:/usr/games:/opt/libunsn/bin
PERL_BADLANG (unset)
SHELL=/usr/bin/zsh

Yves Orton

unread,
Apr 16, 2004, 8:15:56 AM4/16/04
to perl5-...@perl.org

FWIW I agree that Data::Dumper should probably have this. However I have
some reservations.

Currently Data::Dumper doesnt use subs to do its thing at all. Other dumpers
like Data::Dump and Data::Dump::Streamer do however. One question I think
has been of where the responsibility of require()ing or use()ing the module
lies. Data::Dump IIRC takes the view that the dump will include the require
statement, and in Data::Dump::Streamer I decided that it wont include it.
Related questions are that should simply use()ing Data::Dumper provide the
required subs? If so should the dump output use() them into the right
namespace, or should it call directly in the dumper module or into the
loaded module. In Data::Dump I believe the call is into the second party
module (Symbol::gensym) and in Data::Dump::Streamer the person evaling the
dump is expected to have use()d Data::Dump::Streamer qw(:undump);

Anyway, I dont claim that my choices are correct here but I think its worth
thinking about before patching Data::Dumper.

Also, I seem to recall that Scalar::Util::dualvar doesnt work on some
builds, how should Data::Dumper handle that properly?

And once all these policies are decided there are a whole host of attributes
that Data::Dumper doesnt handle that are resolvable by allowing and patching
dumper to emit the appropriate sub calls: Readonlyness, aliases, blessed
regexes with overriden stringification, blessed format refs, anonymous
typeglobs, and restricted hashes are some that come mind now. forward
references to members of composite structures are another Data::Dumper
failing, but thats resolvable without recourse to external subs (i m pretty
sure anyway).

Food for thought.
Yves
ps: Data::Dump::Streamer doesnt handle dualvar either. :-( Ill have to fix
that.


h...@crypt.org

unread,
Apr 16, 2004, 8:59:55 AM4/16/04
to perl5-...@perl.org
Zefram (via RT) <perlbug-...@perl.org> wrote:
:$ perl -MData::Dumper -we '$Data::Dumper::Useqq=1; print Dumper($!)'

:$VAR1 = "Bad file descriptor";
:$ perl -I. -MData::Dumper -we '$Data::Dumper::Useqq=1; print Dumper($!)'
:$VAR1 = dualvar(2, "No such file or directory");

Hmm, that should probably be:
$VAR1 = do { require Scalar::Util; Scalar::Util::dualvar(2, "No such file or directory"); };

Hugo

Rafael Garcia-Suarez

unread,
Apr 16, 2004, 10:17:21 AM4/16/04
to Orton, Yves, perl5-...@perl.org
Orton, Yves wrote:
>
> FWIW I agree that Data::Dumper should probably have this. However I have
> some reservations.

I share these; Data::Dumper is a simple and a fast tool ; IMHO a
specialized CPAN module would be a better place to have a really good,
accurate and nit-picking dumper that reconstitutes every information it
can find (and you list some below).

...

Yves Orton

unread,
Apr 19, 2004, 5:33:37 AM4/19/04
to Rafael Garcia-Suarez, Orton, Yves, perl5-...@perl.org
> > FWIW I agree that Data::Dumper should probably have this.
> However I have
> > some reservations.
>
> I share these; Data::Dumper is a simple and a fast tool ; IMHO a
> specialized CPAN module would be a better place to have a really good,
> accurate and nit-picking dumper that reconstitutes every
> information it
> can find (and you list some below).

For the record the only one of the below that Data::Dump::Streamer doesnt
handle is the dualvar stuff. and thats mostly cause I forgot about it this
weekend.

Regarding Speed. DDS is a lot slower than DD. BUT, I believe that many or
even all of the below can be done without sacrificing speed. In fact some of
the techniques I use in DDS could be used in DD to make it more memory
efficient without sacrificing speed and handle most of the below. (classic
example is that it does NOT need to keep track of having seen any variables
with a refcount of less than 2 (or 3 depending on your POV, XS or Perl) as
these variables CANNOT cause a cyclic link and as such can simply be
traversed without keeping track fo them, furthermore dumping an SV with a
refcount larger than 2 suggests its multiply referenced, possibly even
aliased, and as such needs to be managed carefully. These types of checks
would actually speed things up not slow them down), Ive been meaning to
look into it. But my C is barely up to the task and DD has historically had
a caveat from Sarathy that it doesnt get changed unless the change is in
both the C and and the Perl.

0 new messages