Thank you Rony. 👏
I have had to use terrible kludges to get over the otherwise remarkably usable JSON class's habit
of turning JSON booleans into ooRexx booleans. This will be a great boon.
+1 to adding this to the language proper.
Jon
On Thu, 2 Feb 2023 at 12:37, Rony G. Flatscher <rony.flatsc...@wu.ac.at> wrote:
"json.cls" as distributed with ooRexx 5.0.0 has one (actually two)
limitation which can be
regarded to be a bug:
* It cannot handle JSON booleans properly: when reading a JSON file with
boolean values and
creating a JSON file from ooRexx the boolean values will not show up,
rather their ooRexx
numeric representations of "0" and "1".
In the past I came up with a solution for this problem which was not
"liked" and was 30%
slower than json.cls (sounds dramatic, but in today's world with such power
horses in the
hands of end-users may be negligeable, but still, one being made aware of
this made it less
attractive).
As the above limitation is really a problem if one wants to use ooRexx
json.cls and exchange
proper JSON with other systems, e.g. via curl, I came up with a version
(starting out with
the current json.cls) that does the following in addition:
* It adds support for JSON true and false: just send .json~true or
.json~false. The
resulting JsonBoolean objects behave like ooRexx .true and .false (both
strings with the
numeric values "0" and "1") and can be used interchangeably
o when reading a JSON file, JSON booleans will be represented with
the appropriate
.json~true or .json~false values
o when writing a JSON file, any JSON boolean value will be properly
encoded with
"false" and "true"
* It adds generic support for MapCollection and OrderedCollection instead
of restricting
support to Directory and Array,
* It uses StringTable instead of Directory for reading in JSON data,
* Although JSON is a string encoding, which could be read by humans,
there are two
observable properties that do not make it human-friendly:
o by default the encoding is "minimized" such that no ignorable
whitespace (usually
used for making JSON better legible e.g. cf. Wikipedia's JSON [1]
sample) is contained,
o there is no sorted order of name/value pairs (per specification no
order is implied,
yet for humans having a sorted order in the JSON encoded data makes
it possible to
quickly check whether certain name/values pairs exist or not
without affecting any
JSON importer)
the replacement version will create by default minimized JSON
encodings, however it will
sort name/value pairs by name to ease reading by humans
* as this is Rexx/ooRexx it is made possible to create a "legible", a
"human-oriented" JSON
encoding in two ways: when creating a JSON instance or when sending the
toJson message
one can supply .true which causes the produced JSON encoding to be
formatted with
ignorable whitespace such that it will be easy to see the structure and
spot name/value
pairs therein; yet, the produced JSON is still JSON and can be
processed without problems,
* two new convenience class methods for reading from and writing to files
are defined:
fromJsonFile(fileName) and toJsonFile(fileName, ooRexxObject [,
legible=.true])
Here the JSON sample given at [1]:
{
"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":[
"Catherine",
"Thomas",
"Trevor"
],
"spouse":null
}
Here the minimized rendering with the replacement version of json.cls:
{"address":{"city":"New York","postalCode":"10021-3100","state":"NY","streetAddress":"21 2nd
Street"},"age":27,"children":["Catherine","Thomas","Trevor"],"firstName":"John","isAlive":true,"lastName":"Smith","phoneNumbers":[{"number":"212 555-1234","type":"home"},{"number":"646
555-4567","type":"office"}],"spouse":null}
Here the legible rendering with the replacement version of json.cls:
{
"address": {
"city": "New York",
"postalCode": "10021-3100",
"state": "NY",
"streetAddress": "21 2nd Street"
},
"age": 27,
"children": [
"Catherine",
"Thomas",
"Trevor"
],
"firstName": "John",
"isAlive": true,
"lastName": "Smith",
"phoneNumbers": [
{
"number": "212 555-1234",
"type": "home"
},
{
"number": "646 555-4567",
"type": "office"
}
],
"spouse": null
}
---
Here an ooRexx program that creates a structure which will get encoded as
minimized and
legible JSON:
-- create a Rexx structure
d=.directory~new
d["firstName"] = "Mary"
d["lastName" ] = "Doe"
d["children" ] = .list~of("Maribel", "John", "Annabel")
d["married" ] = .json~false
d["born" ] = "2001-02-02"
d["yearBorn" ] = 2001
d["bestMan" ] = .nil
j = .json~new
say j~toJson(d) -- write minimized JSON
say "---"
say j~toJson(d,.true) -- write legible JSON
::requires "json.cls" -- get access to the JSON class
Here the output of the above program:
{"bestMan":null,"born":"2001-02-02","children":["Maribel","John","Annabel"],"firstName":"Mary","lastName":"Doe","married":false,"yearBorn":2001}
---
{
"bestMan": null,
"born": "2001-02-02",
"children": [
"Maribel",
"John",
"Annabel"
],
"firstName": "Mary",
"lastName": "Doe",
"married": false,
"yearBorn": 2001
}
---
The replacement json.cls and the adjusted official json.tesgroup can be
found in my sandbox
at <https://sourceforge.net/p/oorexx/code-0/HEAD/tree/sandbox/rony/json/>
<https://sourceforge.net/p/oorexx/code-0/HEAD/tree/sandbox/rony/json/>.
Performance when reading and writing is comparable to 5.0's json.cls.
---rony
[1] Wikipedia JSON: <https://en.wikipedia.org/wiki/JSON>
<https://en.wikipedia.org/wiki/JSON>