What is this JSON, anyway?
Anonym
JSON (JavaScript Object Notation) has been mentioned in quite a few IDL and ENVI blog posts, and it is gradually becoming popular among IDL programmers for transmitting and storing information. In fact, JSON is the format of choice for defining Custom ENVITasks, and ENVI began saving preferences in JSON format instead of internal savefiles beginning in ENVI 5.2.
Why is JSON such a popular tool among IDL programmers?
Most likely, the simplicity and readability of the JSON format makes it more preferable to IDL users than similar formats such as XML. Additionally, the well-defined structure of JSON makes it more versatile than plain text.
IDL's JSON_SERIALIZE and JSON_PARSE routines make passing information between JSON text and IDL variables very easy. Compare these one-line calls to the complex code you would need in order to parse or create an XML file using IDLffXMLDOMDocument.
For an example of using JSON to save and restore information, see this blog post.
How does JSON work?
Let's take a look inside the JSON format to learn about how it works.
JSON can contain nested objects or arrays. An object is denoted with { and }, and an array is denoted with [ and ].
Object - contains key-value pairs |
OrderedHash (or plain hash if order isn't important) |
Array - contains items of arbitrary type, child lists, or child objects |
List |
Items in an array are comma separated, and an object's key-value pairs are denoted with "name": value, also separated by commas.
JSON can contain four different types of values:
String - enclosed in quotation marks.
-- Cannot contain a quotation mark or other special characters. |
String |
Number
-- Exponential notation OK (i.e. 1.602E-19) |
Number |
Boolean (true or false) |
IDL Boolean (!true or !false) |
null |
!null |
Note about numbers: IDL assumes the highest possible precision (Double if the number contains a decimal point, Long64 if there is no decimal point).
Implied Print - Example showing IDL to JSON
Using the traditional HELP or PRINT call on a list or hash does not always provide the most helpful result, especially when lists and hashes are nested within each other.
myHash = OrderedHash($
'Name', 'Ben', $
'Date', '12 Nov 2015', $
'Colors', ['red', 'yellow', 'blue', 'green', 'black'], $
'Other Items', OrderedHash($
'Numbers', [1,2,3], $
'Should I get more coffee?', !true, $
'Number of items in my backpack', 0, $
'Items in my backpack', !null))
PRINT, myHash
IDL will display:
Name: Ben
Date: 12 Nov 2015
Colors: red ...
Other Items: HASH <ID=268466 NELEMENTS=4>
And if you try to call HELP, myHash
IDL will display:
MYHASH ORDEREDHASH <ID=268553 NELEMENTS=4>
...which is even less helpful. However, when using Implied Print on a list or hash, IDL will show a very readable JSON string.
myHash
IDL prints:
{
"Name": "Ben",
"Date": "12 Nov 2015",
"Colors": ["red", "yellow", "blue", "green", "black"],
"Other Items": {
"Numbers": [1, 2, 3],
"Should I get more coffee?": true,
"Number of items in my backpack": 0,
"Items in my backpack": null
}
}
Additionally, implied print can be used to print a list or hash into a JSON file in this same readable format. This is more useful than printing the result of JSON_SERIALIZE into the file because the result of JSON_SERIALIZE is a single one-line string.
OPENW, unit, 'C:\scratch\json_example.json', /GET_LUN
PRINTF, unit, myHash, /IMPLIED_PRINT
FREE_LUN, unit
A note about booleans
OK, why do I mention using the !true and !false boolean values in IDL, when most IDL code just uses one or zero?
Traditionally, IDL has never had true boolean values. Instead, the logical "true" was represented with the number 1, and the logical "false" was represented with the number 0. This has been accepted by most IDL programmers for many years. The consequence of this, however, is that booleans in JSON were translated to integers in IDL, causing misrepresentation of the true value, and there was no way to use IDL to write a boolean into JSON text. This is, in fact, one of the main reason IDL began supporting !true and !false, along with the Boolean function in IDL 8.4. However, out of tradition and habit, many IDL programmers still use 1 and 0 to represent true and false.
References
In addition to referencing the IDL and ENVI documentation pages, I used the following website as a reference when writing this blog, which is the official website of the JSON format: www.json.org