Thank you Jon, for your thumbs up! Will wait a day or two before committing to 
trunk.

---rony


On 02.02.2023 13:42, Sahananda Sahananda wrote:
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>

_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to