Sketch of how to solve this kind of problem for all syntactically tricky
.WHICH cases:

class ObjAt {
        method make(*@items) {
                self.new(@items.map({
                        "(" ~
                        (.^isa(ObjAt) ?? .Str !!
                                .Str.subst(/<[\(\)\!]>/,
                                        { sprintf("!\%d", .ord - 32) }, :g))
                        ~ ")"
                }).join(" "))
        }
        method WHICH(ObjAt:D:) { ObjAt.make(self.WHAT.WHICH, self) }
}

class Mu {
        method WHICH(Mu:D:) { ObjAt.make(self.WHAT.WHICH, nqp::objectid(self)) }
}

class Str {
        method WHICH(Str:D:) { ObjAt.make(self.WHAT.WHICH, self) }
}

class Int {
        method WHICH(Int:D:) { ObjAt.make(self.WHAT.WHICH, self) }
}

class Pair {
        method WHICH(Pair:D:) {
                ObjAt.make(self.WHAT.WHICH, $!key.WHICH, $!value.VAR.WHICH)
        }
}

class Set {
        method WHICH(Set:D:) {
                ObjAt.make(self.WHAT.WHICH,
                        %!elems.keys.sort.map({ ObjAt.new($_) }))
        }
}

In summary: centralise the logic for unambiguously representing a
sequence of object identities and strings.  Individual classes should
only have to present the right elements that will go into an identity,
not put it together themselves.

-zefram

Reply via email to