Dumping
Perl 6
AmsterdamX.pm, 8 Jun 2017
ThePerlReview•www.theperlreview.com
DumpingPerl6
Sponsored in part by a grant from
ThePerlReview•www.theperlreview.com
DumpingPerl6
Plain
my $rx = rx/ <[ a .. z ]> <[ 1 .. 9 ]> /;
my $string = ':::abc123::';
my $match = $string ~~ $rx;
put $match;
c1
ThePerlReview•www.theperlreview.com
DumpingPerl6
.gist
my $rx = rx/ <[ a .. z ]> <[ 1 .. 9 ]> /;
my $string = ':::abc123::';
my $match = $string ~~ $rx;
say $match; # put $match.gist
「c1」
ThePerlReview•www.theperlreview.com
DumpingPerl6
.perl
my $rx = rx/ <[ a .. z ]> <[ 1 .. 9 ]> /;
my $string = ':::abc123::';
my $match = $string ~~ $rx;
put $match.perl;
Match.new(list => (), made => Any,
pos => 7, hash => Map.new(()), orig =>
":::abc123::", from => 5)
ThePerlReview•www.theperlreview.com
DumpingPerl6
Pretty::Printer
use Pretty::Printer; # From Jeff Goff
my $rx = rx/ <[ a .. z ]> <[ 1 .. 9 ]> /;
my $string = ':::abc123::';
my $match = $string ~~ $rx;
Pretty::Printer.new.pp: $match;
Any
ThePerlReview•www.theperlreview.com
DumpingPerl6
method _pp($ds,$depth)
{
my Str $str;
given $ds.WHAT
{
when Hash { $str ~= self.Hash($ds,$depth) }
when Array { $str ~= self.Array($ds,$depth) }
when Pair { $str ~= self.Pair($ds,$depth) }
when Str { $str ~= $ds.perl }
when Numeric { $str ~= ~$ds }
when Nil { $str ~= q{Nil} }
when Any { $str ~= q{Any} }
}
return self.indent-string($str,$depth);
}
ThePerlReview•www.theperlreview.com
DumpingPerl6
PrettyDump
use PrettyDump;
my $rx = rx/ <[ a .. z ]> <[ 1 .. 9 ]> /;
my $string = ':::abc123::';
my $match = $string ~~ $rx;
put PrettyDump.new.dump: $match;
ThePerlReview•www.theperlreview.com
DumpingPerl6
Match.new(
:from(5),
:hash(Map.new()),
:list($()),
:made(Mu),
:orig(":::abc123::"),
:pos(7),
:to(7)
)
ThePerlReview•www.theperlreview.com
DumpingPerl6
By Type
ThePerlReview•www.theperlreview.com
DumpingPerl6
method _pp($ds,$depth)
{
my Str $str;
given $ds.WHAT
{
# Check more derived types first.
when Match { $str ~= self.Match($ds,$depth) }
when Hash { $str ~= self.Hash($ds,$depth) }
when Array { $str ~= self.Array($ds,$depth) }
when Map { $str ~= self.Map($ds,$depth) }
when List { $str ~= self.List($ds,$depth) }
when Pair { $str ~= self.Pair($ds,$depth) }
when Str { $str ~= $ds.perl }
when Numeric { $str ~= ~$ds }
when Nil { $str ~= q{Nil} }
when Any { $str ~= q{Any} }
}
return self.indent-string($str,$depth);
}
ThePerlReview•www.theperlreview.com
DumpingPerl6
Per Class
ThePerlReview•www.theperlreview.com
DumpingPerl6
class SomeClass {
…
method PrettyDump ( $pretty, $ds, $depth ) {
…
}
}
my $pretty = PrettyDump.new;
my $some-object = SomeClass.new;
put $pretty.dump: $some-object;
ThePerlReview•www.theperlreview.com
DumpingPerl6
use PrettyDump;
my $pretty = PrettyDump.new;
my Int $a = 137;
put $pretty.dump: $a;
my $b = $a but role {
method PrettyDump ( $pretty, $depth = 0 ) {
"({self.^name}) {self}";
}
};
put $pretty.dump: $b;
ThePerlReview•www.theperlreview.com
DumpingPerl6
method dump ( $ds, $depth = 0 ) {
put "In dump. Got ", $ds.^name;
my Str $str;
if $ds.can: 'PrettyDump' {
$str ~= $ds.PrettyDump: self;
}
elsif $ds ~~ Numeric {
$str ~= self.Numeric: $ds, $depth;
}
elsif self.can: $ds.^name {
my $what = $ds.^name;
$str ~= self."$what"( $ds, $depth );
}
else {
die "Could not handle " ~ $ds.perl;
}
return self.indent-string: $str, $depth;
}
ThePerlReview•www.theperlreview.com
DumpingPerl6
Per Object
ThePerlReview•www.theperlreview.com
DumpingPerl6
Decorate the Dumper
my $pretty = PrettyDump.new;
class SomeClass { … }
my $handler = sub ( $pretty, $ds, Int $depth = 0 ) {
...
}
$pretty.add-handler: 'SomeClass', $handler;
put $pretty.dump: $SomeClass-object;
ThePerlReview•www.theperlreview.com
DumpingPerl6
method dump ( $ds, Int $depth = 0 --> Str ) {
my Str $str = do {
# If the PrettyDump object has a user-defined handler
# for this type, prefer that one
if self.handles: $ds.^name {
self!handle: $ds, $depth;
}
# The object might have its own method to dump
# its structure
elsif $ds.can: 'PrettyDump' {
$ds.PrettyDump: self;
}
# If it's any sort of Numeric, we'll handle it
# and dispatch further
elsif $ds ~~ Numeric {
self!Numeric: $ds, $depth;
}
…
ThePerlReview•www.theperlreview.com
DumpingPerl6
# If we have a method name that matches the class, we'll
# use that.
elsif self.can: $ds.^name {
my $what = $ds.^name;
self."$what"( $ds, $depth );
}
# If the class inherits from something that we know
# about, use the most specific one that we know about
elsif $ds.^parents.grep(
{ self.can: $_.^name } ).elems > 0 {
my Str $str = '';
for $ds.^parents -> $type {
my $what = $type.^name;
next unless self.can( $what );
$str ~= self."$what"(
$ds, $depth, "{$ds.^name}.new(", ')' );
last;
}
$str;
}
…
ThePerlReview•www.theperlreview.com
DumpingPerl6
# If we're this far and the object has a .Str method,
# we'll use that:
elsif $ds.can: 'Str' {
"({$ds.^name}): " ~ $ds.Str;
}
# Finally, we'll put a placeholder method there
else {
"(Unhandled {$ds.^name})"
}
};
return self!indent-string: $str, $depth;
}
ThePerlReview•www.theperlreview.com
DumpingPerl6
Not Data::Dumper
• Does not produce eval-able code
• Does not know what it has already seen
• Missing a few formatting features
ThePerlReview•www.theperlreview.com
DumpingPerl6
What else might it do?
• Handle more data types
• More configurable formatting options
• Formatting hooks
• Send email
ThePerlReview•www.theperlreview.com
DumpingPerl6
Questions

Dumping Perl 6 (AmsterdamX.pm)