On Mon, 20 Oct 2014 09:00:24 -0700, j...@johnkingsley.ca wrote:
> Hi,
> 
> When I define a gist() method, it doesn't get called when I expected
> it to be called.
> 
> This occurs when you call gist() not on the object directly, but
> instead
> on another object which uses the class where the gist() is defined.
> 
> So if you are defining a gist() method on your class, you pretty much
> need to do it on every class in your program for it to be useful.
> I would argue it would be better to allow programmers to define gist
> on an incremental fashion.
> 
> The problem is here in the core:
>      multi method gist(Mu:D:) { self.perl }
> If a gist method isn't defined on a class, then it uses .perl for
> every attribute,
> even when attributes may have a .gist method.
> 
> Test below, with output.
> 
> cheers, John
> 
> $ perl6 -v
> This is perl6 version 2014.09 built on MoarVM version 2014.09
> 
> Test:
> ================================
> #!/usr/bin/env perl6
> 
> class Coord {
>      has Int $.x;
>      has Int $.y;
>      multi method gist(Coord:D:) {
>          "L($.x,$.y)";
>      }
> }
> 
> class Route1 {
>      has Coord @.loc;
> }
> 
> class Route2 {
>      has Coord @.loc;
>      multi method gist(Route2:D:) {
>          "Route2(" ~ @.loc.map({.gist}).join(", ") ~ ")";
>      }
> }
> 
> my $r1 = Route1.new(loc => [Coord.new(x => 0, y => 0), Coord.new(x =>
> 0, y => 1)]);
> note "Got: " ~ $r1.gist;
> note "Exp: " ~ "Route1.new(loc => Array[Coord].new(L(0,0), L(0,1)))";
> 
> my $r2 = Route2.new(loc => [Coord.new(x => 0, y => 0), Coord.new(x =>
> 0, y => 1)]);
> note "Got: " ~ $r2.gist;
> note "Exp: " ~ "Route2(L(0,0), L(0,1))";
> ================================
> 
> Output:
> ================================
> Got: Route1.new(loc => Array[Coord].new(Coord.new(x => 0, y => 0),
> Coord.new(x => 0, y => 1)))
> Exp: Route1.new(loc => Array[Coord].new(L(0,0), L(0,1)))
> Got: Route2(L(0,0), L(0,1))
> Exp: Route2(L(0,0), L(0,1))
> ================================


FWIW, I tried the patch below, but that caused a bunch of spectest breakage 
from things that do assume that Mu.gist is implemented as Mu.perl.

It's almost if it should be trying Foo.gist, if that's not available then 
Foo.perl, and only then go to Mu.perl, which is kinda messy.



    diff --git a/src/core/Mu.pm b/src/core/Mu.pm
    index 6f53d66..a560dbd 100644
    --- a/src/core/Mu.pm
    +++ b/src/core/Mu.pm
    @@ -580,7 +580,20 @@ Perhaps it can be found at 
https://docs.perl6.org/type/$name";
    
        proto method gist(|) { * }
        multi method gist(Mu:U:) { '(' ~ self.^shortname ~ ')' }
    -    multi method gist(Mu:D:) { self.perl }
    +    multi method gist(Mu:D:) {
    +        nqp::if(
    +          nqp::eqaddr(self,IterationEnd),
    +          "IterationEnd",
    +          self.gistseen(self.^name, {
    +              my @attrs;
    +              for self.^attributes().flat.grep: { .has_accessor } -> $attr 
{
    +                  my $name := substr($attr.Str,2);
    +                  @attrs.push: $name ~ ' => ' ~ $attr.get_value(self).gist
    +              }
    +              self.^name ~ '.new' ~ ('(' ~ @attrs.join(', ') ~ ')' if 
@attrs)
    +          })
    +        )
    +    }
    
        method perlseen(Mu:D \SELF: $id, $perl, *%named) {
            my $sigil = nqp::iseq_s($id, 'Array') ?? '@'

Reply via email to