.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Data::Dumper::Simple 3pm" .TH Data::Dumper::Simple 3pm "2022-10-22" "perl v5.34.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Data::Dumper::Simple \- Easily dump variables with names .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& use Data::Dumper::Simple; \& warn Dumper($scalar, @array, %hash); \& warn Dumper($scalar, \e@array, \e%hash); \& warn Dumper $scalar, @array, %hash; .Ve .SH "ABSTRACT" .IX Header "ABSTRACT" .Vb 6 \& This module allow the user to dump variables in a Data::Dumper format. \& Unlike the default behavior of Data::Dumper, the variables are named \& (instead of $VAR1, $VAR2, etc.) Data::Dumper provides an extended \& interface that allows the programmer to name the variables, but this \& interface requires a lot of typing and is prone to tyops (sic). This \& module fixes that. .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\f(CW\*(C`Data::Dumper::Simple\*(C'\fR is actually a source filter that replaces all instances of \f(CW\*(C`Dumper($some, @args)\*(C'\fR in your code with a call to \&\f(CW\*(C`Data::Dumper\->Dump()\*(C'\fR. You can use the one function provided to make dumping variables for debugging a trivial task. .PP Note that this is primarily a debugging tool. \f(CW\*(C`Data::Dumper\*(C'\fR offers a bit more than that, so don't expect this module to be more than it is. .PP Note that if you strongly object to source filters, I've also released Data::Dumper::Names. It does what this module does by it uses PadWalker instead of a source filter. Unfortunately, it has a few limitations and is not as powerful as this module. Think of Data::Dumper::Names as a \*(L"proof of concept\*(R". .SS "The Problem" .IX Subsection "The Problem" Frequently, we use \f(CW\*(C`Data::Dumper\*(C'\fR to dump out some variables while debugging. When this happens, we often do this: .PP .Vb 2 \& use Data::Dumper; \& warn Dumper($foo, $bar, $baz); .Ve .PP And we get simple output like: .PP .Vb 3 \& $VAR1 = 3; \& $VAR2 = 2; \& $VAR3 = 1; .Ve .PP While this is usually what we want, this can be confusing if we forget which variable corresponds to which variable printed. To get around this, there is an extended interface to \f(CW\*(C`Data::Dumper\*(C'\fR: .PP .Vb 4 \& warn Data::Dumper\->Dump( \& [$foo, $bar, $baz], \& [qw/*foo *bar *baz/] \& ); .Ve .PP This provides much more useful output. .PP .Vb 3 \& $foo = 3; \& $bar = 2; \& $baz = 1; .Ve .PP (There's more control over the output than what I've shown.) .PP You can even use this to output more complex data structures: .PP .Vb 4 \& warn Data::Dumper\->Dump( \& [$foo, \e@array], \& [qw/*foo *array/] \& ); .Ve .PP And get something like this: .PP .Vb 5 \& $foo = 3; \& @array = ( \& 8, \& \*(AqOvid\*(Aq \& ); .Ve .PP Unfortunately, this can involve a lot of annoying typing. .PP .Vb 4 \& warn Data::Dumper\->Dump( \& [$foo, \e%this, \e@array, \e%that], \& [qw/*foo *that *array *this/] \& ); .Ve .PP You'll also notice a typo in the second array ref which can cause great confusion while debugging. .SS "The Solution" .IX Subsection "The Solution" With \f(CW\*(C`Data::Dumper::Simple\*(C'\fR you can do this instead: .PP .Vb 2 \& use Data::Dumper::Simple. \& warn Dumper($scalar, @array, %hash); .Ve .PP Note that there's no need to even take a reference to the variables. The output of the above resembles this (sample data, of course): .PP .Vb 12 \& $scalar = \*(AqOvid\*(Aq; \& @array = ( \& \*(AqData\*(Aq, \& \*(AqDumper\*(Aq, \& \*(AqSimple\*(Aq, \& \*(AqRocks!\*(Aq \& ); \& %hash = ( \& \*(Aqit\*(Aq => \*(Aqdoes\*(Aq, \& \*(AqI\*(Aq => \*(Aqhope\*(Aq, \& \*(Aqat\*(Aq => \*(Aqleast\*(Aq \& ); .Ve .PP Taking a reference to an array or hash works as expected, but taking a reference to a scalar is effectively a no-op (because it can turn into a confusing reference to a reference); .PP .Vb 3 \& my $foo = { hash => \*(Aqref\*(Aq }; \& my @foo = qw/foo bar baz/; \& warn Dumper ($foo, \e@foo); .Ve .PP Produces: .PP .Vb 8 \& $foo = { \& \*(Aqhash\*(Aq => \*(Aqref\*(Aq \& }; \& $foo = [ \& \*(Aqfoo\*(Aq, \& \*(Aqbar\*(Aq, \& \*(Aqbaz\*(Aq \& ]; .Ve .PP Note that this means similarly named variables can get quite confusing, as in the example above. .PP If you already have a \f(CW&Dumper\fR function, you can specify a different function name with the \f(CW\*(C`as\*(C'\fR key in the import list: .PP .Vb 2 \& use Data::Dumper::Simple as => \*(Aqdisplay\*(Aq; \& warn display( $scalar, @array, %hash ); .Ve .PP Also, if you really, really can't stand typing \f(CW\*(C`warn\*(C'\fR or \f(CW\*(C`print\*(C'\fR, you can turn on \f(CW\*(C`autowarn\*(C'\fR: .PP .Vb 2 \& use Data::Dumper::Simple as => \*(Aqdisplay\*(Aq, autowarn => 1; \& display($scalar, @array, $some\->{ data }); .Ve .PP Or you can send the output (as a list) to a different function: .PP .Vb 1 \& use Data::Dumper::Simple as => \*(Aqdebug\*(Aq, autowarn => \*(Aqto_log\*(Aq; \& \& sub to_log { \& my @data = @_; \& # some logging function \& } \& \& debug( \& $customer => @order_nums \& ); # yeah, we support the fat comma "=>" and newlines .Ve .SH "EXPORT" .IX Header "EXPORT" The only thing exported is the \fBDumper()\fR function. .PP Well, actually that's not really true. Nothing is exported. However, a source filter is used to automatically rewrite any apparent calls to \f(CW\*(C`Dumper()\*(C'\fR so that it just Does The Right Thing. .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 4 Data::Dumper \- Stringified perl data structures .IP "\(bu" 4 Filter::Simple \- Simplified source filtering .SH "BUGS" .IX Header "BUGS" This module uses a source filter. If you don't like that, don't use this. There are no known bugs but there probably are some as this is \fBAlpha Code\fR. .SH "LIMITATIONS" .IX Header "LIMITATIONS" .IP "\(bu" 4 Calling with a sub .Sp Do not try to call \f(CW\*(C`Dumper()\*(C'\fR with a subroutine in the argument list: .Sp .Vb 1 \& Dumper($foo, some_sub()); # Bad! .Ve .Sp The filter gets confused by the parentheses. Your author was going to fix this but it became apparent that there was no way that \f(CW\*(C`Dumper()\*(C'\fR could figure out how to name the return values from the subroutines, thus ensuring further breakage. So don't do that. .IP "\(bu" 4 Multiple enreferencing .Sp Getting really crazy by using multiple enreferencing will confuse things (e.g., \&\f(CW\*(C`\e\e\e\e\e\e$foo\*(C'\fR), don't do that, either. I might use \f(CW\*(C`Text::Balanced\*(C'\fR at some point to fix this if it's an issue. .IP "\(bu" 4 Slices .Sp List and hash slices are not supported at this time. .IP "\(bu" 4 String interpolation .Sp \&\f(CW\*(C`Dumper($foo)\*(C'\fR can potentially interpolate if it's in a string. This is because of a weird edge case with \*(L"\s-1FILTER_ONLY\s0 code\*(R" which caused a failure on some items being dumped. I've fixed that, but made the module a wee bit less robust. This will hopefully be fixed in the next release of Text::Balanced. .IP "\(bu" 4 Line numbers may be wrong .Sp Because this module uses a source filter, line numbers reported from syntax or other errors may be thrown off a little. .Sp This is probably a bug in the source filter implementation, which should use \f(CW\*(C`#line\*(C'\fR directives. As a workaround until this is fixed, put a directive (such as \f(CW\*(C`#line 10000\*(C'\fR) a few lines ahead of the suspected bug. If the error is reported as happening in line 10007, you know to look about eight lines below your directive for the bug. Be sure to remove the bogus directive once you find the bug! .IP "\(bu" 4 The parentheses are optional, but the syntax isn't bulletproof .Sp If you try, it's not hard to confuse the parser. Patches welcome. .PP Note that this is not a drop-in replacement for \f(CW\*(C`Data::Dumper\*(C'\fR. If you need the power of that module, use it. .SH "AUTHOR" .IX Header "AUTHOR" Curtis \*(L"Ovid\*(R" Poe, .PP Reverse the name to email me. .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Copyright 2004 by Curtis \*(L"Ovid\*(R" Poe .PP This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.