DEV Community

Bruce Axtens
Bruce Axtens

Posted on

JavaScript polymorphism in Google Apps Script

(Updated 2020-06-04 to include Boolean)

Here I am betraying my lack of understanding of polymorphism and thus feeding my imposter syndrome experience.

String.prototype.quoted = function () {
  return  "'" + this.replace(/'/g,"\\'") + "'";
}

Number.prototype.quoted = function () {
  return String(this);
}

Boolean.prototype.quoted = function () {
    return this ? "true" : "false";
}
Enter fullscreen mode Exit fullscreen mode

There you have the same method name on three different data types. That's probably a boot-camp fail straight up, especially extending core objects like String, Number and Boolean.

With those in mind, I have this Google Apps Script function that I use to log the attributes of a subset of DocumentApp elements.

function LogChildren(body) {
    function getInnerText(child) {
        switch (child.getType().toString()) {
            case "PARAGRAPH":
                return child.asParagraph().getText();
                break;
            case "TABLE":
                return child.asTable().getText();
                break;
            default:
                return child.asText().getText();
                break;
        }
    }
    function getStyles(child) {
        const attribs = child.getAttributes();
        const attribList = [];
        for (let att in attribs) {
            try {
                if (null !== attribs[att])
                    attribList.push(att.quoted() + " : " + attribs[att].quoted());
            }
            catch (E) {
            }
        }
        return "{" + attribList.join(", ") + "}";
    }
    const childCount = body.getNumChildren();
    for (let c = 0; c < childCount; c++) {
        const child = body.getChild(c);
        Logger.log("[%s] %s = %s %s", c, child.getType().toString(), getInnerText(child), getStyles(child));
    }
}
Enter fullscreen mode Exit fullscreen mode

The use of the three versions of .quoted() is in the getStyles function above, namely

if (null !== attribs[att])
    attribList.push(att.quoted() + " : " + attribs[att].quoted());
Enter fullscreen mode Exit fullscreen mode

So sometimes attribs[att] is a String or a Number or a Boolean. One way of handling whether to put quotes around attribs[att] or not would be to write a function which uses typeof to decide what the data type is and then handle it appropriately. Instead of doing it that way I'm banking on the interpreter already knowing the data type and then running the appropriate .quoted.

This works now, but sure as anything there's going to be a time when there'll be other things to quote that aren't as amenable to having their objects extended. As it stands, however, this is diagnostic code and won't be appearing in production.

Top comments (1)

Collapse
 
australopithecus2 profile image
australopithecus2

The problem really is with the nature of typing in computer languages, which has been reinvented as an extension of set theory to retroconvert a series of business cases in running payrolls and firing missiles.

So your quoting is appropriate to the need to return an utterance, quoted.

It would require (and welcome) further coercions for Booleans, Dates and Times, which are numbers that aren't numbers proper, but numbers in a socially agreed context.

This has to do with the semiotics of programming languages: they masquerade as science but they are properly speaking a form of speech. I think it was Naur who said programming languages exist for three purposes: to describe a solution to a problem, to communicate that solution to a fellow worker for checking, and only then for the steps to be carried out by a computer.

Your code highlights the problems in algol-inspired representations of reality, that anything that isn't agreed isn't representable. So fractions, complexes, numbers with precision, vectors with units, values with errors, multiple solutions to square root calculations all get to be unrepresented, and to question this is to be impractical and (oddly enough) not living in the "real world".

Algol the star was named for a Gorgon, a creature capable of turning the world into a lifeless stone. Perhaps this outcome with numbers and types was what we might have expected.