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.
Sadly, go-spew and GopherJS don’t play together well. Or they didn’t, until recently.
When executing a common go-spew function in GopherJS, I would get something like this:
$ nodejs jstest.js /home/jonhall/go/src/github.com/flimzy/jstest/jstest.js:1475 throw err; ^ TypeError: upf.$get is not a function at init (/home/jonhall/go/src/github.com/flimzy/jstest/jstest.js:24518:14) at Object.$init (/home/jonhall/go/src/github.com/flimzy/jstest/jstest.js:26410:8) ...
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 github.com/davecgh/go-spew/spew TypeError: upf.$get is not a function at init (/github.com/davecgh/go-spew/spew/bypass.go:88:3) at Object.$init (/home/jonhall/go/src/github.com/davecgh/go-spew/test.166243863:32502:8) ...
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?