package App::Framework::Base::Object::DumpObj ;
=head1 NAME
App::Framework::Base::Object::DumpObj - Dump out an objects contents
=head1 SYNOPSIS
use App::Framework::Base::Object::DumpObj ;
=head1 DESCRIPTION
Given a data object (scalar, hash, array etc) prints out that objects contents
=head1 REQUIRES
=head1 DIAGNOSTICS
Setting the debug flag to level 1 prints out (to STDOUT) some debug messages, setting it to level 2 prints out more verbose messages.
=head1 AUTHOR
Steve Price C<< <sdprice at cpan.org> >>
=head1 BUGS
None that I know of!
=head1 INTERFACE
=over 4
=cut
use strict ;
use Carp ;
use Cwd ;
our $VERSION = "2.002" ;
require Exporter ;
our @ISA = qw(Exporter);
our @EXPORT =qw(
);
our @EXPORT_OK =qw(
prt_data
prtstr_data
exclude
debug
verbose
$DEBUG
$VERBOSE
$PRINT_OBJECTS
$PREFIX
);
#============================================================================================
# USES
#============================================================================================
#============================================================================================
# GLOBALS
#============================================================================================
our $DEBUG = 0 ;
our $VERBOSE = 0 ;
our $PRINT_OBJECTS = 0 ;
our $QUOTE_VALS = 0 ;
our $PREFIX = 0 ;
my $level ;
my %already_seen ;
my $prt_str ;
my %excludes ;
#============================================================================================
# EXPORTED
#============================================================================================
#---------------------------------------------------------------------------------------------------
=item B<debug($level)>
Set debug print options to B<$level>.
0 = No debug
1 = standard debug information
2 = verbose debug information
=cut
sub debug
{
my ($flag) = @_ ;
my $old = $DEBUG ;
if (defined($flag))
{
# set this module debug flag & sub-modules
$DEBUG = $flag ;
}
return $old ;
}
#---------------------------------------------------------------------------------------------------
=item B<verbose($level)>
Set vebose print options to B<$level>.
0 = Non verbose
1 = verbose print
=cut
sub verbose
{
my ($flag) = @_ ;
my $old = $VERBOSE ;
if (defined($flag))
{
# set this module verbose flag & sub-modules
$VERBOSE = $flag ;
}
return $old ;
}
#---------------------------------------------------------------------------------------------------
=item B<print_objects_flag($flag)>
Set option for printing out objects to B<$flag>.
0 = Do not print contents of object [DEFAULT]
1 = print contents of object
=cut
sub print_objects_flag
{
my ($flag) = @_ ;
my $old = $PRINT_OBJECTS ;
if (defined($flag))
{
# set this module debug flag & sub-modules
$PRINT_OBJECTS = $flag ;
}
return $old ;
}
#---------------------------------------------------------------------------------------------------
=item B<quote_vals_flag($flag)>
Set option quoting the values to B<$flag>.
0 = Do not quote values [DEFAULT]
1 = Print values inside quotes
This is useful for re-using the output directly to define an array/hash
=cut
sub quote_vals_flag
{
my ($flag) = @_ ;
my $old = $QUOTE_VALS ;
if (defined($flag))
{
# set this module debug flag & sub-modules
$QUOTE_VALS = $flag ;
}
return $old ;
}
#---------------------------------------------------------------------------------------------------
=item B<exclude(@list)>
Set the list of excluded HASH keys. Any keys in a HASH that match the name(s) in the list will not be
displayed.
Specifying an empty list clears the excludes
=cut
sub exclude
{
my (@list) = @_ ;
%excludes = () ;
%excludes = map {$_ => 1} @list ;
return ;
}
#---------------------------------------------------------------------------------------------------
=item B<prefix($prefix)>
Prefix all output lines with B<$prefix>
Returns previous value
=cut
sub prefix
{
my ($prefix) = @_ ;
my $old = $PREFIX ;
if (defined($prefix))
{
# set this module debug flag & sub-modules
$PREFIX = $prefix ;
}
return $old ;
}
#---------------------------------------------------------------------
=item B<prtstr_data(@list)>
Create a multiline string of all items in the list. Handles scalars, hashes (as an array),
arrays, ref to scalar, ref to hash, ref to array, object.
=cut
sub prtstr_data
{
my (@data_list) = @_ ;
$level = -1 ;
%already_seen = () ;
$prt_str = '' ;
foreach my $var (@_)
{
if (ref ($var))
{
_print_ref($var);
}
else
{
_print_scalar($var);
}
}
return $prt_str ;
}
#---------------------------------------------------------------------
=item B<prt_data(@list)>
Print out each item in the list. Handles scalars, hashes (as an array),
arrays, ref to scalar, ref to hash, ref to array, object.
=cut
sub prt_data
{
my (@data_list) = @_ ;
prtstr_data(@data_list) ;
print $prt_str ;
}
# ============================================================================================
# UNEXPORTED BY DEFAULT
# ============================================================================================
#---------------------------------------------------------------------------------------------------
sub _print_scalar
{
++$level;
_print_indented ($_[0]);
--$level;
}
#---------------------------------------------------------------------------------------------------
sub _print_ref
{
my $r = $_[0];
if (!defined($r))
{
_print_indented ("undef\n");
return;
}
elsif (exists ($already_seen{$r}))
{
_print_indented ("# $r (Seen earlier)\n");
return;
}
else
{
$already_seen{$r}=1;
}
my $ref_type = ref($r);
if ($ref_type eq "ARRAY")
{
_print_array($r);
}
elsif ($ref_type eq "SCALAR")
{
_print_scalar($$r);
_print_str(" # Ref -> $r\n");
}
elsif ($ref_type eq "HASH")
{
_print_hash($r);
}
elsif ($ref_type eq "REF")
{
++$level;
_print_indented("# Ref -> ($r)\n");
_print_ref($$r);
--$level;
}
else
{
_print_indented ("# OBJECT $ref_type\n");
# If required (and we can) print out the object
if ($PRINT_OBJECTS)
{
my $obj_ref_str = "$r" ;
if ($obj_ref_str =~ /ARRAY/)
{
_print_array($r);
}
elsif ($obj_ref_str =~ m/HASH/)
{
_print_hash($r);
}
}
}
}
#---------------------------------------------------------------------------------------------------
sub _print_array
{
my ($r_array) = @_;
++$level;
_print_indented ("[ # $r_array\n");
foreach my $var (@$r_array)
{
if (ref ($var))
{
_print_ref($var);
}
else
{
_print_scalar($var);
_print_str(",\n");
}
}
_print_indented ("],\n");
--$level;
}
#---------------------------------------------------------------------------------------------------
sub _print_hash
{
my($r_hash) = @_;
my($key, $val);
++$level;
_print_indented ("{ # $r_hash\n");
# while (($key, $val) = each %$r_hash)
foreach my $key (sort keys %$r_hash)
{
#print "<< key <$key> r_hash <$r_hash> >>\n" ;
my $val = $r_hash->{$key} ;
if (defined($val))
{
$val = ($val ? $val : '0');
}
else
{
$val = 'undef' ;
}
++$level;
if (exists($excludes{$key}))
{
_print_indented ("$key => ...\n");
}
else
{
if (ref ($val))
{
_print_indented ("$key => \n");
_print_ref($val);
}
else
{
_print_indented ("$key => $val,\n");
}
}
--$level;
}
_print_indented ("},\n");
--$level;
}
#---------------------------------------------------------------------------------------------------
sub _print_indented
{
my $spaces = " " x $level;
if ($PREFIX)
{
# print prefix at start of a line
if (!$prt_str)
{
_print_str("$PREFIX") ;
}
elsif ($prt_str =~ m/(.*)\n$/)
{
_print_str("$PREFIX") ;
}
}
_print_str("${spaces}") ;
_print_val($_[0]) ;
# $prt_str .= "\n" ;
}
#---------------------------------------------------------------------------------------------------
sub _print_val
{
my ($val) = @_ ;
if (defined($val))
{
_print_str("$val") ;
# Print positive numerical value in hex too
if ($val =~ m/(^|\s+)(\d+)$/)
{
_print_str(sprintf " # [0x%0x]", $2) if ($2 > 0) ;
}
}
else
{
_print_str("undef") ;
}
}
#---------------------------------------------------------------------------------------------------
sub _print_str
{
my ($str) = @_ ;
$prt_str .= $str ;
}
# ============================================================================================
# END OF PACKAGE
=back
=cut
1;
__END__