What is json, we begin

In the first epoch of my professional life, we scraped along without JSON files. So, while I knew that package.json was a file that kept cropping up in node.js, I wasn’t really clear on “what is JSON?” thing was all about, or even what the acronym stood for. So, OK, it stands for JavaScript Object Notation.

Now we big, manly C programmers had a thing called a header file, a .h file. Boom. Same thing. Or, well, actually not. Let me start over.

A JSON file is a file with a .json extension that contains a bunch of data represented in various kinds of JavaScript constructs, but it seems like most of the time what you see are objects with name-value pairs separated by commas. Like:

{
  "foo": "bar,
  "rodentType": "mouse"
}

The list of value pairs is an object, so you use your basic object declaration–you put things between curly braces, like so (this example borrowed from the Wikipedia entry on json:

{
  "firstName": "John",
  "lastName": "Smith",
  "isAlive": true,
  "age": 27,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    }
  ],
  "children": [],
  "spouse": null
}

And you’ll note from the example that you can also have arrays, between square brackets.

Indeed, the point of the JSON business, really, is to make it really simple to take an object that’s been set up in some JavaScript code, like for example an object that contains a bunch of to-do items, with each having a title property and a boolean flag, isDone, which is set true when the todo item has been done:

0: {title: "Clean your room", isDone: false}
1: {title: "Do your homework", isDone: false}

Let’s say this data is stored in an object variable called items. We’d like to be able to plop this into the localStorage object, which is a built in capability of the browser that writes the object to disk on the local computer.

Backing up a little, remember that a JSON file is entirely text-based, so what we write to local storage must, even if it started life as an object, be a string. There’s a library for this (there’s a library for everything these days), aptly called JSON. Thus:

let JSONstr = JSON.stringify(items)

turns the items object into a string that looks like:

[{"title":"sfdsf","isDone":false},{"title":"make breakfast","isDone":false}]

This can then be written to local storage:

localStorage.setItem('items', JSONstr )

Which is cool, and which enables us to do this process in reverse, using localStorage.setItem( ‘items’) to retrieve this particular bit of data, after which we turn it from a string back into an array of objects by using JSON.parse( JSONstr). There is nothing the least bit fancy about this really–it’s just another case of programming taking a fairly mundane task (packing and unpacking a file in a particular format) and doing the work once to the benefit of all.

A million years ago I remember being kind of thrilled to learn the strtok() function in the C language. It’s not nearly as smart as JSON, but enables you to break a string into pieces, where each piece is delimited by the specific character (or set of characters) you use in the function call. So, for instance, you could use a comma as the delimiter as a way to get at the pieces of a line extracted from a CSV (comma-separated values) file. You could suck a text file in line by line and then pull the line apart with successive calls to strtok().

Parenthetically, this gets at what I loved about C, namely, that it uses pointers unapologetically, giving you full license to totally screw things up. In the case of strtok(), the function returns a pointer to a string. So, we hope, space was allocated to store whatever string is sitting at the location pointed to by the string variable we pass to strtok. That’s just basic hygiene in C. Let’s say the string is “Give me a wheel of oaken wood.” and it’s at address A. If we use a space (” “) as our delimiter, we’re going to be returned the address A. In other words, the return value points to the start of the first token, which is “Give”.

But how do we know where the token ends? After all, a C string ends with a null. The null that ends the string we passed in is just after the period in “Give me a wheel of oaken wood.” But the strtok function actually changes the value of the string and puts a null where the space was after the word “Give”. Holy crap. We passed in a string that had seven words in it, but if we look at the string we passed in now, it is nothing more than “Give”.

Meanwhile, strtok() has remembered–beyond the context of this particular call to the function–that the next token begins at the address A+the length of the token last returned. How can you not just love this crap? I’m being serious here, mind you. I think this is awesome. Anyway, if you have a loop where you run through all the tokens in the original string, you’ll be handed back a pointer that advances along the string at address A, all the while dropping nulls in at the ends of each token.

You can see, probably, why people get into all sorts of trouble with C and why polite people are no longer allowed to code in the horrible, horrible language. But, hey, it’s the efficient way to do this sort of work. Most of the time, you don’t care if the string gets chopped up and it’s fastest to just poke through it in memory right where it stands. If you need an unaltered copy, then make one before you start tokenizing.

Anyway, in C, you really have to fully understand what you’re doing with pointers and the like. There’s a power in that, but on the other hand there’s something to be said for the extreme ease of just plunking a whole object into local storage (regardless of how local storage is implemented) using two lines of code. And it’s pretty blissful that the stringify() function hides all the mickey-mouse details of scanning for square brackets and curly braces and so on. Which is possible, getting back to the subject at hand, because JSON is well-specified.

In the interest of a full accounting, I should add that JSON is pretty much the same concept as YAML, which started life as the acronym Yet Another Markup Language. Apparently, it’s now properly “YAML ain’t markup language.” Using a name that is quasi-recursive might have been cute back when “GNU’s Not Unix” was coined, but this is just tired and dumb.

That said, YAML is visually easier to read and–wonder of wonders–allows comments. Somehow, wretchedly, JSON does not. And it would be so damned easy… But if you are working in JavaScript and you have an object, then when you look at the object stored in a JSON file, it will look exactly (well, approximately exactly) the same as the object in .JS file. Which is handy.


Comments

Leave a Reply