.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) .\" .\" 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 .\" ======================================================================== .\" .IX Title "Devel::DDCWarn 3pm" .TH Devel::DDCWarn 3pm "2020-06-13" "perl v5.30.3" "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" Devel::DDCWarn \- Easy printf\-style debugging with Data::Dumper::Compact .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Devel::DDCWarn; \& \& my $x = Dwarn some_sub_call(); # warns and returns value \& my @y = Derr other_sub_call(); # prints to STDERR and returns value \& \& my $x = DwarnT X => some_sub_call(); # warns with tag \*(AqX\*(Aq and returns value \& my @y = DerrT X => other_sub_call(); # similar .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Devel::DDCWarn is a Devel::Dwarn equivalent for Data::Dumper::Compact. .PP The idea, basically, is that it's incredibly annoying to start off with code like this: .PP .Vb 1 \& return some_sub_call(); .Ve .PP and then realise you need the value, so you have to write: .PP .Vb 3 \& my @ret = some_sub_call(); \& warn Dumper [ THE_THING => @ret ]; \& return @ret; .Ve .PP With Devel::DDCWarn, one can instead write: .PP .Vb 1 \& return DwarnT THE_THING => some_sub_call(); .Ve .PP and expect it to Just Work. .PP To integrate with your logging, you can do: .PP .Vb 3 \& our $L = sub { $log\->debug("DDC debugging: ".$_[0] }; \& ... \& return DtoT $L, THE_THING => some_sub_call(); .Ve .PP When applying printf debugging style approaches, it's also very useful to be able to do: .PP .Vb 1 \& perl \-MDevel::DDCwarn ... .Ve .PP and then within the code being debugged, abusing the fact that a prefix of :: is short for main:: so we can add: .PP .Vb 1 \& return ::DwarnT THE_THING => some_sub_call(); .Ve .PP and if we forget to remove them, the lack of command-line Devel::DDCWarn exported into main:: will produce a compile time failure. This is exceedingly useful for noticing you forgot to remove a debug statement \fIbefore\fR you commit it along with the test and fix. .SH "EXPORTS" .IX Header "EXPORTS" All of these subroutines are exported by default. .PP Data::Dumper::Compact is referred to herein as \s-1DDC.\s0 .SS "Dwarn" .IX Subsection "Dwarn" .Vb 2 \& my $x = Dwarn make_x(); \& my @y = Dwarn make_y_array(); .Ve .PP \&\f(CW\*(C`warn()\*(C'\fRs the \*(L"Df\*(R" \s-1DDC\s0 dump of its input, then returns the first element in scalar context or all arguments in list context. .SS "Derr" .IX Subsection "Derr" .Vb 2 \& my $x = Derr make_x(); \& my @y = Derr make_y_array(); .Ve .PP prints the \*(L"Df\*(R" \s-1DDC\s0 dump of its input to \s-1STDERR,\s0 then returns the first element in scalar context or all arguments in list context. .SS "DwarnT" .IX Subsection "DwarnT" .Vb 2 \& my $x = Dwarn TAG => make_x(); \& my @y = Dwarn TAG => make_y_array(); .Ve .PP Like \*(L"Dwarn\*(R", but passes its first argument, the tag, through to \*(L"DfT\*(R" but skips it for the return value. .SS "DerrT" .IX Subsection "DerrT" .Vb 2 \& my $x = Derr TAG => make_x(); \& my @y = Derr TAG => make_y_array(); .Ve .PP Like \*(L"Derr\*(R", but accepts a tag argument that is included in the output but is skipped for the return value. .SS "Dto" .IX Subsection "Dto" .Vb 1 \& Dto(sub { warn $_[0] }, @args); .Ve .PP Like \*(L"Dwarn\*(R", but instead of warning, calls the subroutine passed as the first argument \- this function is low level but still returns the \f(CW@args\fR. .SS "DtoT" .IX Subsection "DtoT" .Vb 1 \& DtoT(sub { err $_[0] }, $tag, @args); .Ve .PP The tagged version of Dto. .SS "Df" .IX Subsection "Df" .Vb 2 \& my $x = Df($thing); \& my $y = Df(@other_things); .Ve .PP A single value is returned formatted by \s-1DDC.\s0 Multiple values are transformed to a \s-1DDC\s0 list. .SS "DfT" .IX Subsection "DfT" .Vb 2 \& my $x = Df($tag => $thing); \& my $y = Df($tag => @other_things); .Ve .PP A tag plus a single value is formatted as a two element list. A tag plus multiple values is formatted as a list containing the tag and a list of the values. .PP If the tag is an arrayref, is assumed to be: .PP .Vb 1 \& my $x = Df([ $tag, $tweak ] => @things); .Ve .PP and what's dumped is \f(CW\*(C`<$tweak\-\*(C'\fR(@things)>> instead of \f(CW@things\fR. This means that e.g. one can write: .PP .Vb 1 \& return Dwarn([ foo => sub { +{ @_ } } ], %things); .Ve .PP to output the things as a hashref while still returning a flattened hash. .SH "CONFIGURATION" .IX Header "CONFIGURATION" .Vb 1 \& use Devel::DDCWarn \e%options, ...; \& \& perl \-MDevel::DDCWarn=\-optname,value,\-other,value ...; \& \& $Devel::DDCWarn::ddc = Data::Dumper::Compact\->new(\e%options); .Ve .PP Options passed as a hashref on a \f(CW\*(C`use\*(C'\fR line or using \- prefixing on the command line are used to initialise the Data::Dumper::Compact object. .PP Note that this primarily being a debugging and/or scripting oriented tool, if something initialises us again later, this will reset the (single) global \&\f(CW$ddc\fR used by this code and change all output through the process. .PP However, if you need a localised change of formatting style, \f(CW$ddc\fR is a full fledged global so you are absolutely allowed to \f(CW\*(C`local\*(C'\fR it: .PP .Vb 2 \& my $ddc = Data::Dumper::Compact\->new(\e%my_local_options); \& local $Devel::DDCWarn::ddc = $ddc; .Ve .PP If you have a convincing reason for using this functionality in a way where the globality is a bug rather than a feature, please start a conversation with the authors so we can figure out what to do about it. .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright (c) 2019 the \*(L"\s-1AUTHOR\*(R"\s0 in Data::Dumper::Compact and \&\*(L"\s-1CONTRIBUTORS\*(R"\s0 in Data::Dumper::Compact as listed in Data::Dumper::Compact. .SH "LICENSE" .IX Header "LICENSE" This library is free software and may be distributed under the same terms as perl itself. See .