How I got go-spew to work with GopherJS

go-spew is a very handy library used for dumping arbitrarily complex data structures in a (roughly) human-readable format.

This is immensely helpful when debugging or writing automated tests in programs. Coupled with a package like go-difflib, it can make comparing the expected and actual results of a test not only easy, but into something approaching fun.

6654647Much of my time lately is spent hacking on projects to be compiled by GopherJS, the Go-to-JavaScript compiler.

Sadly, go-spew and GopherJS don’t play together well. Or they didn’t, until recently.

You see, go-spew does some pretty nitty-gritty introspection on data structures, to report on the sizes of variables, and memory addresses and whatnot. These features are not supported by GopherJS, as code compiled by GopherJS is run within a JavaScript interpreter, where direct memory access isn’t available, and pointers are emulated.

When executing a common go-spew function in GopherJS, I would get something like this:

$ nodejs jstest.js
        throw err;

TypeError: upf.$get is not a function
    at init (/home/jonhall/go/src/
    at Object.$init (/home/jonhall/go/src/

I decided I wasn’t happy with this state of things, so I set out to investigate. And I stumbled upon a year-old commit to the go-spew package, with the description:

Add support for limited mode without unsafe pkg.

This commit adds support for compiling spew without the unsafe package.
When compiled without the unsafe package, some of the more advanced
features such as invoking stringers on pointers from non-pointer
variables and unexported struct fields are not available.

This looked promising, so I set out to see if go-spew would work with GopherJS with this new build tag:

    $ gopherjs test --tags=disableunsafe
TypeError: upf.$get is not a function
    at init (/
    at Object.$init (/home/jonhall/go/src/

Ugh. I’ve hacked on GopherJS a few times before, so I wasn’t afraid to start debugging it. Pretty quickly I found that GopherJS was simply ignoring build tags during testing. I filed a bug, then found and submitted a patch which was quickly merged.

My next step was to submit a pull request to the go-spew project to treat the js tag the same way it treated the disableunsafe tag. This patch was quickly merged as well.

Now go-spew works safely, and out of the box with GopherJS, and I’m a happy camper! Isn’t open-source software great?

Leave a Reply

Your email address will not be published. Required fields are marked *