Data-Printer
Data-Printer copied to clipboard
confusing 'changing output targets' documentation
from https://metacpan.org/pod/Data::Printer
Changing output targets
By default, p() will be set to use STDERR. As of version 0.27, you can set up the 'output' property so Data::Printer outputs to several different places:
output => 'stderr' - Standard error. Same as *STDERR output => 'stdout' - Standard output. Same as *STDOUT output => $filename - Appends to filename. output => $file_handle - Appends to opened handle output => \$scalar - Appends to that variable's content
appantly this code
use Data::Printer output => $filename
does not work since $filename is undefined at compile time
Please believe me when I say this was very confusing to me. I don't think the output=>$file_handle
works either. I would like an updated example that works, or something like that. Or another way to set the output to a file. I only ask because I don't understand much about the Data::Printer class.
Thanks!
also when writing to a file, the file will not be line-buffered. this means you're probably just better off redirecting stdout, since there is no way to flush the output of p() before you look for output.
Hello! Thank you for using Data::Printer and for taking the time to file this issue.
You are absolutely right: variables aren't defined at compile time unless placed inside BEGIN
blocks. What I meant by $filename
is "any string that is neither 'stdout' nor 'stderr'" - though you could of course use a variable too. This should have been clearer on the documentation, and I'll try to make it right on the upcoming releases. Meanwhile, there are many ways to get it working:
- hardcoding the filename:
use Data::Printer output => '/path/to/some/file.log';
# (...)
p $data;
- requiring Data::Printer at runtime:
# (...)
require DDP; DDP->import( output => $filename );
# (...)
DDP::p($data);
- making sure $filename is defined before DDP is loaded:
my $filename;
BEGIN { $filename = '/path/to/some/file.log'; }
BEGIN { use Data::Printer output => $filename; }
# (...)
p $data;
- Passing the output parameter on each p() or np() call:
use DDP;
# (...)
p $data, output => $filename;
ou can of course add this to some logging method of your own:
use Data::Printer;
my $filename = '/path/to/some/file.log';
# (...)
logme( $somedata );
# (...)
sub logme ($data) {
p $data, output => $filename;
}
- Putting the filename, hardcoded, on a configuration file (
.dataprinter
), then have DDP load it automatically.
Finally, while you can autoflush STDOUT with local $| = 1
, you're also right that there is no option to flush the contents after each print (I'll look into it). Meanwhile you could pass a handle with flush activated, like:
use IO::Handle;
use Data::Printer;
# (...)
open my $fh, '>>', '/path/to/some/data.log' or die $!;
$fh->autoflush;
# (...)
p $data, output => $fh;
Hope this helps!
wow. Excellent response. All of these would fix the issue.
Thanks!
Also I can see that logging certain things to some files, and different things to a different logfile is actually a feature I plan to use.
Can you also permit the use of objects (e.g. Path::Tiny) as an output target? A reference to an object that overloads stringification is also a useful string.