perl5ever has asked for the wisdom of the Perl Monks concerning the following question:

Is there a way (or another module) to get the output of Devel::Peek to a string instead of printing to STDERR?

I like Devel::Peek over Data::Dumper because it gives me the UTF8 flag setting (and it'll do it recursively as it traverses hashes and arrays).

Replies are listed 'Best First'.
Re: Devel::Peek output to a string?
by repellent (Priest) on Feb 25, 2009 at 20:30 UTC
    By redirecting STDERR.


    UPDATE: Changed code to take into account suggestion by ELISHEVA.
      If the above routine is run on certain *nixes (but not Windows), each call to the above subroutine will print out a "Use of uninitialized value in subroutine" warning along with the dump.

      This is apparently due to a bug in Devel::Peek::Dump (see my note below). To eliminate the warning on those systems you will need to make the following change to the subroutine suggested by repellent:

      Best beth

Re: Devel::Peek output to a string?
by ELISHEVA (Prior) on Feb 25, 2009 at 22:19 UTC

    As repellent has pointed out, the way to get Devel::Peek::Dump to write to a string is to redirect STDERR to a string. However, if you are running on certain *nixes (Debian-Etch/Perl 5.8.8 and possibly others), the first time you call Devel::Peek::Dump whilst STDERR is redirected to a string, you may see a "Use of uninitialized value in subroutine" warning. This warning does not seem to appear on Windows (so saith ikegami who tried it on Windows for me).

    As near as we could tell, this a bug in Devel::Peek::Dump. It has been reported and ticketed as bug 63498. The bug is rated low severity, so you may have to wait a while before this particular annoyance goes away.

    Best, beth

    Update: more clearly identified systems with potential problems

      Could it be that the string variable just has to be initialized to an empty string?
      use strict; use warnings; use Devel::Peek; # initialized here my $sOut = ""; close(STDERR); open(STDERR, ">", \$sOut) or die "Can't redirect STDERR to \\\$sOut"; my $s=1; Devel::Peek::Dump $s; Devel::Peek::Dump $s; print "<<$sOut>>\n";
        Apparently so! I thought I made sure of that.
        Great catch! But here's a wrinkle. Other common uses of STDERR redirected to string, namely print, do not require the string variable to be initialized. For example:
        use strict; use warnings; my $sOut; close(STDERR); open(STDERR, ">", \$sOut) or die "Can't redirect STDERR to \\\$sOut"; print STDERR "Hello World!\n"; print $sOut;

        happily outputs "Hello World" without generating a warning (at least on my system). Somehow, I don't think the Devel::Peek::Dump behavior qualifies as Inconsistent for the sake of convenience :-)

        Best, beth

      Hmmm... I don't see the bug on my Linux box:
      $ cat /etc/redhat-release Red Hat Enterprise Linux WS release 4 (Nahant Update 4) $ perl -v This is perl, v5.8.5 built for i686-linux-thread-multi Copyright 1987-2004, Larry Wall Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using `man perl' or `perldoc perl'. If you have access to + the Internet, point your browser at http://www.perl.com/, the Perl Home Pa +ge.

      UPDATE: I was wrong. My use warnings; was commented out. Bug confirmed on my platform.
Re: Devel::Peek output to a string?
by Tux (Canon) on Mar 01, 2009 at 11:08 UTC

    Dropping in after a reference to this was posted on the perl5 mailing list.

    The redirection to STDERR was exactly the reason why I wrote Data::Peek

    use Data::Peek; my %hash = ( boo => [ 1..3 ], blah => "ab\nc\x{20ac}" ); my $dump; open my $fh, ">", \$dump; DDump_IO ($fh, \%hash, 6); close $fh; print $dump;

    This uses perl internals to dump data structures, instead of using perl code to traverse and dump.

    SV = RV(0x8804c8) at 0x8804b8 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x880530 SV = PVHV(0x866db0) at 0x880530 REFCNT = 2 FLAGS = (PADMY,SHAREKEYS) ARRAY = 0x86ef70 (0:7, 2:1) hash quality = 62.5% KEYS = 2 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 Elt "blah" HASH = 0x4566b599 SV = PV(0x85a098) at 0x8804a0 REFCNT = 1 FLAGS = (POK,pPOK,UTF8) PV = 0x86aa10 "ab\nc\342\202\254"\0 [UTF8 "ab\nc\x{20ac}"] CUR = 7 LEN = 8 Elt "boo" HASH = 0x73a487c9 SV = RV(0x85c150) at 0x85c140 REFCNT = 1 FLAGS = (ROK) RV = 0x85c2f0 SV = PVAV(0x85d490) at 0x85c2f0 REFCNT = 1 FLAGS = () ARRAY = 0x86e970 FILL = 2 MAX = 2 ARYLEN = 0x0 FLAGS = (REAL) Elt No. 0 SV = IV(0x85c4b0) at 0x85c4b8 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1 Elt No. 1 SV = IV(0x880588) at 0x880590 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 2 Elt No. 2 SV = IV(0x880570) at 0x880578 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 3

    Enjoy, Have FUN! H.Merijn