Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Introduce Any.gistseen
This method allows a developer to easily create a .gist method that is
aware of self-referential structures (such can occur with arrays, lists,
hashes and pairs).  This replaces the ad-hoc code found so far.
  • Loading branch information
lizmat committed Nov 25, 2015
1 parent 8ef5a59 commit 2e38ba6
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 104 deletions.
20 changes: 20 additions & 0 deletions src/core/Any.pm
Expand Up @@ -176,6 +176,26 @@ my class Any { # declared in BOOTSTRAP
!! self
}

method gistseen(Any:D: $id, $gist) {
if %*gistseen -> $gistseen {
my $WHICH := self.WHICH;
if $gistseen.AT-KEY($WHICH) -> \semaphore {
semaphore = 2;
"{$id}_{self.WHERE}";
}
else {
$gistseen.AT-KEY($WHICH) = 1;
$gistseen.DELETE-KEY($WHICH) == 2
?? "(\\{$id}_{self.WHERE} = $gist())"
!! $gist()
}
}
else {
my %*gistseen = :TOP;
self.gistseen($id,$gist)
}
}

# auto-vivifying
proto method push(|) is nodal {*}
multi method push(Any:U \SELF: |values) {
Expand Down
19 changes: 1 addition & 18 deletions src/core/Array.pm
Expand Up @@ -708,24 +708,7 @@ my class Array { # declared in BOOTSTRAP
}

multi method gist(Array:D:) {
if %*gistseen -> $gistseen {
my $WHICH := self.WHICH;
if $gistseen.AT-KEY($WHICH) -> \semaphore {
semaphore = 2;
"Array_{self.WHERE}";
}
else {
$gistseen.AT-KEY($WHICH) = 1;
my $result = self.map({.gist}).join(' ');
$gistseen.DELETE-KEY($WHICH) == 2
?? "(\\Array_{self.WHERE} = [$result])"
!! "[$result]"
}
}
else {
my %*gistseen = :TOP;
self.gist
}
self.gistseen('Array', { '[' ~ self.map({.gist}).join(' ') ~ ']' } )
}

multi method WHICH(Array:D:) {
Expand Down
33 changes: 9 additions & 24 deletions src/core/Hash.pm
Expand Up @@ -54,30 +54,15 @@ my class Hash { # declared in BOOTSTRAP
}

multi method gist(Hash:D:) {
if %*gistseen -> $gistseen {
my $WHICH := self.WHICH;
if $gistseen.AT-KEY($WHICH) -> \semaphore {
semaphore = 2;
"Hash_{self.WHERE}";
}
else {
$gistseen.AT-KEY($WHICH) = 1;
my $result = self.pairs.sort.map( -> $elem {
given ++$ {
when 101 { '...' }
when 102 { last }
default { $elem.gist }
}
} ).join: ', ';
$gistseen.DELETE-KEY($WHICH) == 2
?? "(\\Hash_{self.WHERE} = $result)"
!! $result
}
}
else {
my %*gistseen = :TOP;
self.gist
}
self.gistseen('Hash', {
self.pairs.sort.map( -> $elem {
given ++$ {
when 101 { '...' }
when 102 { last }
default { $elem.gist }
}
} ).join: ', '
})
}

multi method DUMP(Hash:D: :$indent-step = 4, :%ctx?) {
Expand Down
33 changes: 9 additions & 24 deletions src/core/List.pm
Expand Up @@ -569,30 +569,15 @@ my class List does Iterable does Positional { # declared in BOOTSTRAP
}

multi method gist(List:D:) {
if %*gistseen -> $gistseen {
my $WHICH := self.WHICH;
if $gistseen.AT-KEY($WHICH) -> \semaphore {
semaphore = 2;
"List_{self.WHERE}";
}
else {
$gistseen.AT-KEY($WHICH) = 1;
my $result = self.map( -> $elem {
given ++$ {
when 101 { '...' }
when 102 { last }
default { $elem.gist }
}
}).join(' ');
$gistseen.DELETE-KEY($WHICH) == 2
?? "(\\List_{self.WHERE} = ($result))"
!! "($result)"
}
}
else {
my %*gistseen = :TOP;
self.gist
}
self.gistseen('List', {
'(' ~ self.map( -> $elem {
given ++$ {
when 101 { '...' }
when 102 { last }
default { $elem.gist }
}
}).join(' ') ~ ')'
})
}

multi method perl(List:D \SELF:) {
Expand Down
25 changes: 5 additions & 20 deletions src/core/Pair.pm
Expand Up @@ -36,26 +36,11 @@ my class Pair does Associative {
multi method Str(Pair:D:) { $!key ~ "\t" ~ $!value }

multi method gist(Pair:D:) {
if %*gistseen -> $gistseen {
my $WHICH := self.WHICH;
if $gistseen.AT-KEY($WHICH) -> \semaphore {
semaphore = 2;
"Pair_{self.WHERE}";
}
else {
$gistseen.AT-KEY($WHICH) = 1;
my $result = nqp::istype($!key, Pair)
?? '(' ~ $!key.gist ~ ') => ' ~ $!value.gist
!! $!key.gist ~ ' => ' ~ $!value.gist;
$gistseen.DELETE-KEY($WHICH) == 2
?? "(\\Pair_{self.WHERE} = $result)"
!! $result
}
}
else {
my %*gistseen = :TOP;
self.gist
}
self.gistseen('Pair', {
nqp::istype($!key, Pair)
?? '(' ~ $!key.gist ~ ') => ' ~ $!value.gist
!! $!key.gist ~ ' => ' ~ $!value.gist;
})
}

multi method perl(Pair:D: :$arglist) {
Expand Down
19 changes: 1 addition & 18 deletions src/core/Rakudo/Internals.pm
Expand Up @@ -448,24 +448,7 @@ my class Rakudo::Internals {
}

multi method gist(::?CLASS:D:) {
if %*gistseen -> $gistseen {
my $WHICH := self.WHICH;
if $gistseen.AT-KEY($WHICH) -> \semaphore {
semaphore = 2;
"Array_{self.WHERE}";
}
else {
$gistseen.AT-KEY($WHICH) = 1;
my $result = self!gist([], self.shape);
$gistseen.DELETE-KEY($WHICH) == 2
?? "(\\Array_{self.WHERE} = $result)"
!! $result
}
}
else {
my %*gistseen = :TOP;
self.gist
}
self.gistseen('Array', { self!gist([], self.shape) })
}
method !gist(@path, @dims) {
if @dims.elems == 1 {
Expand Down

0 comments on commit 2e38ba6

Please sign in to comment.