Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

"Safe" print?

by dd-b (Monk)
on May 13, 2013 at 22:29 UTC ( [id://1033372] : perlquestion . print w/replies, xml ) Need Help??

dd-b has asked for the wisdom of the Perl Monks concerning the following question:

For logging, and debugging, I often need to print something where I don't really know what it is or whether it's defined. I want to print it in such a way that I can always tell from the output. I don't need the full value (for complex structures).

This seems like such a common need, I'm a little surprised I haven't found anything that does it. Does anybody else have this problem? Is there a solution?

(The aspect that burns me most frequently is an undef variable blowing up the print; I want it to just say "undef" or something. Trying to suppress writing requirements, in hopes of finding something in existence.)

Replies are listed 'Best First'.
Re: "Safe" print?
by McA (Priest) on May 13, 2013 at 22:38 UTC
    use Data::Dumper; my $val = 'something'; print Dumper(\$val);
    There is also Data::Printer or Data::Dump and similar.
Re: "Safe" print?
by LanX (Saint) on May 13, 2013 at 22:39 UTC
    Do you know about Data::Dumper and Data::Dump ?
    lanx@nc10-ubuntu:~$ perl use Data::Dump qw/pp/; $x=[1,2,3]; pp $x; pp $a; __END__ [1, 2, 3] undef
    If yes, please try to explain your problem more detailed.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: "Safe" print?
by ambrus (Abbot) on May 14, 2013 at 08:23 UTC

    If you want undefined values printed as "undef", try

    use 5.010; print $somevalue // "undef";

      ... noting that the "//" operator is, IIRC, a relatively recent addition to the language.   You should have it, but you (or some backwater web-hosting companies who need not be named ...) conceivably might not.   See perldoc perlop on your system; look for the heading “C-style Logical Defined-Or.”

        See that first line in my the code? It says use 5.010;. The // operator was new in perl 5.10. It's not new anymore now.

Re: "Safe" print?
by pemungkah (Priest) on May 15, 2013 at 03:31 UTC
    How about this?
    sub safe_print { for my $item (@_) { print defined $item ? $item : '[undef]'; } }
    Or more condensed:
    sub safe_print { local $_; print map { defined $_ ? $_ : '[UNDEF]' } @_; }
    You'll need to tweak it if you want to support alternate filehandles. Might be easier as an OO class at that point since you have data and actions bound together. Note this probably could use a few extra tweaks, but it should get you on the right road.
    use strict; use warnings; sub new { my($class, $args) = @_; $args = {} unless defined $args; die "Arguments must be a hash ref\n" unless ref($args) eq 'HASH'; my $self = { %$args }; bless $self, $class; return $self; } sub print { my $self = shift; $self->{fh} = *STDOUT unless defined $self->{fh}; my $fh = $self->{fh}; print $fh (map { defined $_ ? $_ : '[UNDEF]' } @_); } 1;
    Using it:
    open my $fh, ">", "foo" or die "Can't open foo: $!\n"; my $printer = SafePrinter->new({fh => $fh}); $printer->print("so it goes", undef, 'and it went', "\n");
    foo contains: so it goesUNDEFand it went </code> Will that do?