#!/usr/bin/perl
use strict;
use warnings;
use Scalar::Util qw(blessed reftype);
sub describe {
my ($data, $indent) = @_;
$indent //= 0;
my $pad = ' ' x $indent;
my $class = blessed($data);
my $r = reftype($data) // '';
return undef unless $r;
if ($r eq 'HASH') {
my (@scalars, @lines);
for my $k (sort keys %$data) {
my $d = describe($data->{$k}, $indent + 1);
if (defined $d) {
push @lines, "$pad $k => $d";
} else {
push @scalars, $k;
}
}
my $out = ($class ? "$class " : "") . "{\n";
$out .= "$pad " . join(", ", @scalars) . "\n" if @scalars;
$out .= $_ for @lines;
$out .= "$pad}\n";
return $out;
}
elsif ($r eq 'ARRAY') {
my @parts;
for my $i (0 .. $#$data) {
push @parts, describe($data->[$i], $indent + 1);
}
if (!grep { defined } @parts) {
return ($class ? "$class " : "") . "[]\n";
}
my $out = ($class ? "$class " : "") . "[\n";
for my $i (0 .. $#parts) {
if (defined $parts[$i]) {
$out .= "$pad $parts[$i]";
} else {
$out .= "$pad ,\n";
}
}
$out .= "$pad]\n";
return $out;
}
return undef;
}
print describe($const) // "(no structure)\n";