planetscape has asked for the wisdom of the Perl Monks concerning the following question:
⭐ (data structures)
I still don't understand my complex data structure. Can Perl
draw me a picture?
Originally posted as a Categorized Question.
Re: How can I visualize my complex data structure?⭐
by planetscape (Chancellor) on Aug 07, 2005 at 22:24 UTC
|
Yes. In the spirit of TMTOWTDI, there are several ways to
represent your data structure. Which you choose is largely up to
you. The information provided below should serve as an overview
only; always consult a module's complete documentation for usage,
bugs, and caveats.
- Dumpvalue
More of a prettyprinter than a serializer, this
method provides the view of your data structure that is most like
the output from Perl's debugger. The output format may be modified
by setting numerous options. Dumpvalue can even dump the
symbol tables of whole packages.
use strict;
use warnings;
use Dumpvalue;
my $ref = {
a => [ 1, 2, 3 ],
b => [
{ X => 1, Y=> 2 },
{
X => [ 1, 2, 3 ],
Y => [ 4, 5, 6 ],
Z => [ 7, 8, 9 ]
},
],
};
print "Dumpvalue:\n";
Dumpvalue->new->dumpValue( $ref );
Output:
Dumpvalue:
'a' => ARRAY(0x460ee8)
0 1
1 2
2 3
'b' => ARRAY(0x4e3e50)
0 HASH(0x4d964c)
'X' => 1
'Y' => 2
1 HASH(0x4e3e14)
'X' => ARRAY(0x4d967c)
0 1
1 2
2 3
'Y' => ARRAY(0x4e3d9c)
0 4
1 5
2 6
'Z' => ARRAY(0x4e3dd8)
0 7
1 8
2 9
- Data::Dumper
Possibly the most popular choice, Data::Dumper outputs
actual Perl code. As such, it is both a prettyprinter
and a serializer. Data::Dumper can handle
self-referential data structures, and evaling
Data::Dumper's output reconstitutes an exact copy of the
original data structure. This module is useful both for saving data
structures to disk and DBM files and for passing them to other
processes. As with Dumpvalue, Data::Dumper's
output is configurable.
use strict;
use warnings;
use Data::Dumper;
my $ref = {
a => [ 1, 2, 3 ],
b => [
{ X => 1, Y=> 2 },
{
X => [ 1, 2, 3 ],
Y => [ 4, 5, 6 ],
Z => [ 7, 8, 9 ]
},
],
};
print "Data::Dumper:\n";
print Dumper( $ref );
Output:
Data::Dumper:
$VAR1 = {
'a' => [
1,
2,
3
],
'b' => [
{
'X' => 1,
'Y' => 2
},
{
'Z' => [
7,
8,
9
],
'X' => [
1,
2,
3
],
'Y' => [
4,
5,
6
]
}
]
};
- YAML's Dump
Another prettyprinter/serializer combo.
YAML's output format is also controllable and hash keys
are sorted by default. Since YAML does not eval to de-serialize, it is safer than
Data::Dumper when you're not sure who else might have
access to your files. Data structures serialized from Perl using
YAML can be accurately read and processed using
YAML in Java, Javascript, PHP, Python, Ruby, and Tcl (and
of course, Perl). Likewise, data structures may be serialized in
any of these languages and be usable by Perl.
use strict;
use warnings;
use YAML;
my $ref = {
a => [ 1, 2, 3 ],
b => [
{ X => 1, Y=> 2 },
{
X => [ 1, 2, 3 ],
Y => [ 4, 5, 6 ],
Z => [ 7, 8, 9 ]
},
],
};
print "YAML::Dump:\n";
print Dump( $ref );
Output:
YAML::Dump:
---
a:
- 1
- 2
- 3
b:
- X: 1
Y: 2
- X:
- 1
- 2
- 3
Y:
- 4
- 5
- 6
Z:
- 7
- 8
- 9
- Data::Dump::Streamer, by demerphq
If it's by our very own demerphq, it must be good.
Data::Dump::Streamer offers more accurate and more
readable output, and uses less memory, than does
Data::Dumper. Hash keys are sorted and the sort order is
configurable. Data::Dump::Streamer's output, like that of
Data::Dumper, may be evaled back to
its original form.
use strict;
use warnings;
use Data::Dump::Streamer;
my $ref = {
a => [ 1, 2, 3 ],
b => [
{ X => 1, Y=> 2 },
{
X => [ 1, 2, 3 ],
Y => [ 4, 5, 6 ],
Z => [ 7, 8, 9 ]
},
],
};
print "Data::Dump::Streamer:\n";
print Dump( $ref );
Output:
Data::Dump::Streamer:
$HASH1 = {
a => [
1,
2,
3
],
b => [
{
X => 1,
Y => 2
},
{
X => [
1,
2,
3
],
Y => [
4,
5,
6
],
Z => [
7,
8,
9
]
}
]
};
See also: Test::Struct
- GraphViz::Data::Structure is one of two modules I know
of that literally draw you a picture of your data structure. Great
for the visually-oriented, but none of the de-serializing or
multi-lingual features of the above alternatives.
use strict;
use warnings;
use GraphViz::Data::Structure;
my $data_structure = {
a => [ 1, 2, 3 ],
b => [
{ X => 1, Y => 2 },
{
X => [ 1, 2, 3 ],
Y => [ 4, 5, 6 ],
Z => [ 7, 8, 9 ]
},
],
};
my $gvds =
GraphViz::Data::Structure->new( $data_structure, Orientation => 'ver
+tical' );
print $gvds->graph()->as_png("gvds.png");
Output
- GraphViz::Data::Grapher is the other of the two, and
happens to be my personal favorite. No reconstituting original
structures or sharing them with other languages such as Python or
Ruby; but this does create very nice illustrations of complex data
structures for documentation or perhaps teaching purposes.
use strict;
use warnings;
use GraphViz::Data::Grapher;
my $structure = {
a => [ 1, 2, 3 ],
b => [
{ X => 1, Y => 2 },
{
X => [ 1, 2, 3 ],
Y => [ 4, 5, 6 ],
Z => [ 7, 8, 9 ]
},
],
};
my $graph = GraphViz::Data::Grapher->new($structure);
print $graph->as_png("gvdg.png");
Output
For more on visualizing hash structure, please see: Not Exactly a Hash Tutorial
References (incomplete and in no
particular order):
| [reply] [d/l] [select] |
|
| [reply] |
Re: How can I visualize my complex data structure?⭐
by Discipulus (Canon) on Nov 11, 2005 at 09:08 UTC
|
Here is a little dumper I wrote some time ago:
my %h2 = (
'AAA' => 'aaa',
'BBB' => 'bbb',
'CCC' => {
'A1' => 'a1',
'B1' => 'b1',
'C1' => {
'A2' => 'a2',
'B2' => 'b2',
'C2' => 'c2END',
},
},
'DDD' => 'ddd',
);
sub ddump
{
my $ref = shift;
my $deep = shift||1;
for my $k ( sort keys %$ref )
{
if ( ref $ref->{$k} )
{
print "\t" x $deep."$k =>\n";
ddump( $ref->{$k}, $deep+1 );
}
else
{
print "\t" x ($deep)."$k => $ref->{$k}\n";
}
}
}
ddump( \%h2 );
Then I found a column by merlyn,
which gave me the idea of dumping into a CGI table structure. The result:
use CGI qw /:all -nph/; #on Win32
$|++;
sub nest
{
my $it = shift;
ref $it ? complex_table($it) : $it
}
sub complex_table
{
my $hr = shift;
# could test here to ensure that $hr is indeed a hash ref.
table( { -border => 2, -bordercolor => 'green', -cellspacing => '0
+', },
map Tr( td( {-valign=>'top'}, $_ ), td( nest( $hr->{$_} ))), s
+ort keys %$hr
);
}
my %h1 = (); # feed your HoH here
print
start_html,
complex_table( \%h1 ),
end_html;
which produces a dump like this:
AAA | aaa | BBB | bbb | CCC | | DDD | ddd |
| [reply] [d/l] [select] |
Re: How can I visualize my complex data structure?⭐
by Xiong (Hermit) on Feb 17, 2010 at 14:14 UTC
|
use strict;
use warnings;
# Enable special comments for debugging and reporting:
use Smart::Comments;
my $data_structure = {
a => [ 1, 2, 3 ],
b => [
{ X => 1, Y => 2 },
{
X => [ 1, 2, 3 ],
Y => [ 4, 5, 6 ],
Z => [ 7, 8, 9 ]
},
],
};
# the following is a "smart comment" which causes a dump of the expres
+sion, using Data::Dumper:
### $data_structure
Produces this output:
### $data_structure: {
### a => [
### 1,
### 2,
### 3
### ],
### b => [
### {
### X => 1,
### Y => 2
### },
### {
### X => [
### 1,
### 2,
### 3
### ],
### Y => [
### 4,
### 5,
### 6
### ],
### Z => [
### 7,
### 8,
### 9
### ]
### }
### ]
### }
Smart::Comments does much, much more than this, too.
| [reply] [d/l] [select] |
|
| [reply] |
Re: How can I visualize my complex data structure?
by Discipulus (Canon) on Nov 17, 2005 at 08:19 UTC
|
hello Monks,
maybe I can give my answer ?!? fantastic !! I was warking on dumping HoH on the screen for a better overview and I wrote this:
my %h2=(
'AAA' => 'aaa',
'BBB' => 'bbb',
'CCC' => {'A1' => a1,
'B1' => 'b1',
'C1' => {'A2' => a2,'B2' => 'b2','C2' => 'c2END'}},
'DDD' => 'ddd',
);
my $ref2 = \%h2;
&ddump($ref2);
sub ddump
{
my $ref = shift;
my $deep = shift||1;
foreach my $k (sort keys %{$ref})
{
if (ref( ${$ref}{$k})) {print "\t" x $deep."$k =>\n";
&ddump (${$ref}{$k}, ($deep+1))
}
else {print "\t" x ($deep)."$k => ${$ref}{$k}\n";}
$deep-1;
}
}
Then I found a column by Merlyn, only 8 year later, that suggested me a new rebus to solve: how about to dump via CGI.pm table ?? or to be precise Hohoh->TableOfTableOfTable here the code:
use warnings;
use CGI qw /:all -nph/; #on Win32
$|++;
$POST_MAX=100;
$DISABLE_UPLOAD=1;
print header();
print start_html();
my %HoHoH = ();#feed your hoh here
my $ref2 = \%HoHoH ;
print &table_center(&complextable($ref2));
print end_html;
sub td_center{{-align=>center} td([@_]); }#separated for customization
sub tr_center {{-align=>center}Tr([@_]); }
sub table_center {
table({-title=>'oOOOo',
-bgcolor=>"#000000",
-border=>1,
-bordercolor=>"red",
-cellspacing=>"0",
-width=>"80%",
-cellpadding=>"0"},
@_);
}
sub complextable
{
my $ref = shift;
my @righe;
foreach my $k (sort keys %{$ref})
{
if (ref( $$ref{$k} ))
{
push @righe,
(&tr_center
(&td_center
($k,(&table_center
(&complextable($$ref{$k}))
)
)
)
) ;
}
else
{
push @righe, (&tr_center(&td_center($k, $$ref{$k} )));
}
}
return @righe;
}
Hope this help. Hope some golf master to squize my homegrown code.
cheers from sunny Roma Lor*
Originally posted as a Categorized Answer. | [reply] [d/l] [select] |
|
|