Hi - I’ve hit some Json where the outputted values (they are field names) are written out in a specific order - and the author hasn’t chosen to use an array to represent those fields in a specific order.
{ ‘field1’ : { ….}, ‘field2’: { … } } I think this is technically incorrect and should be: { [ {‘field1’ : { ….}, ‘field2’: { … } ]} Anyway - given what I’ve got, would it be a terrible idea to create my own version NeoJsonObject and just make it a subclass of OrderedDictionary? I can’t see any issues - but then I might be kidding myself… Tim |
Tim,
> On 7 Jun 2018, at 01:37, Tim Mackinnon <[hidden email]> wrote: > > Hi - I’ve hit some Json where the outputted values (they are field names) are written out in a specific order - and the author hasn’t chosen to use an array to represent those fields in a specific order. > > { ‘field1’ : { ….}, ‘field2’: { … } } > > I think this is technically incorrect and should be: > > { [ {‘field1’ : { ….}, ‘field2’: { … } ]} > > Anyway - given what I’ve got, would it be a terrible idea to create my own version NeoJsonObject and just make it a subclass of OrderedDictionary? > > I can’t see any issues - but then I might be kidding myself… > > Tim Yea, I think you could try making a NeoJSONOrderedObject as a subclass of OrderedDictionary, modelled after NeoJSONObject. Just remember it is implemented using DNU, which will surprise you at one point. Sven |
In reply to this post by Tim Mackinnon
Tim Mackinnon wrote
> Hi - I’ve hit some Json where the outputted values (they are field names) > are written out in a specific order - and the author hasn’t chosen to use > an array to represent those fields in a specific order. > > { ‘field1’ : { ….}, ‘field2’: { … } } > > I think this is technically incorrect and should be: > > { [ {‘field1’ : { ….}, ‘field2’: { … } ]} > > Anyway - given what I’ve got, would it be a terrible idea to create my own > version NeoJsonObject and just make it a subclass of OrderedDictionary? > > I can’t see any issues - but then I might be kidding myself… > > Tim Seems like those are two different JSON objects. The first is what you'd get from a NeoJSONObject holding a Dictionary. The second is what you'd get from a NeoJSONObject holding an Array holding a Dictionary as its only element. Maybe just double check that the right object is getting created. For JSON (https://json.org/) I think the order of the keys does not matter, but the hierarchy does, so making an OrderedDictionary subclass seems extra. -- Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html |
In reply to this post by Sven Van Caekenberghe-2
> Am 07.06.2018 um 07:29 schrieb Sven Van Caekenberghe <[hidden email]>: > > Tim, > >> On 7 Jun 2018, at 01:37, Tim Mackinnon <[hidden email]> wrote: >> >> Hi - I’ve hit some Json where the outputted values (they are field names) are written out in a specific order - and the author hasn’t chosen to use an array to represent those fields in a specific order. >> >> { ‘field1’ : { ….}, ‘field2’: { … } } >> >> I think this is technically incorrect and should be: >> >> { [ {‘field1’ : { ….}, ‘field2’: { … } ]} >> >> Anyway - given what I’ve got, would it be a terrible idea to create my own version NeoJsonObject and just make it a subclass of OrderedDictionary? >> >> I can’t see any issues - but then I might be kidding myself… >> >> Tim > > Yea, I think you could try making a NeoJSONOrderedObject as a subclass of OrderedDictionary, modelled after NeoJSONObject. Just remember it is implemented using DNU, which will surprise you at one point. > Norbert |
> On 7 Jun 2018, at 08:16, Norbert Hartl <[hidden email]> wrote: > > > >> Am 07.06.2018 um 07:29 schrieb Sven Van Caekenberghe <[hidden email]>: >> >> Tim, >> >>> On 7 Jun 2018, at 01:37, Tim Mackinnon <[hidden email]> wrote: >>> >>> Hi - I’ve hit some Json where the outputted values (they are field names) are written out in a specific order - and the author hasn’t chosen to use an array to represent those fields in a specific order. >>> >>> { ‘field1’ : { ….}, ‘field2’: { … } } >>> >>> I think this is technically incorrect and should be: >>> >>> { [ {‘field1’ : { ….}, ‘field2’: { … } ]} >>> >>> Anyway - given what I’ve got, would it be a terrible idea to create my own version NeoJsonObject and just make it a subclass of OrderedDictionary? >>> >>> I can’t see any issues - but then I might be kidding myself… >>> >>> Tim >> >> Yea, I think you could try making a NeoJSONOrderedObject as a subclass of OrderedDictionary, modelled after NeoJSONObject. Just remember it is implemented using DNU, which will surprise you at one point. >> > Wouldn‘t be setting #mapClass: on the reader to OrderedDictionary not enough? Dictionary is the default anyway. > > Norbert Yes, of course, Norbert, it keeps the order: (NeoJSONReader on: '{"BB":1,"CC":2,"AA":3}' readStream) mapClass: OrderedDictionary; next. => an OrderedDictionary('BB'->1 'CC'->2 'AA'->3) NeoJSONWriter toString: (OrderedDictionary new at: #BB put: 1; at: #CC put: 2; at: #AA put: 3; yourself). => '{""BB"":1,""CC"":2,""AA"":3}' It is not functionally 100% the same as a hypothetical NeoJSONOrderedObject, but might do. Sven |
Thanks guys - it seems like I was on the right track.
Making my own NeoJsonObject did work, but I will go back and see if I’m really using the js nature of the values and if for this, just an OrderedDictionary might be clearer. As an aside, I was doing some experiments with prismic.io (a headless cms) and the order of your content when rendering it on a page(generically) is obviously important. Tim Sent from my iPhone > On 7 Jun 2018, at 07:46, Sven Van Caekenberghe <[hidden email]> wrote: > > > >> On 7 Jun 2018, at 08:16, Norbert Hartl <[hidden email]> wrote: >> >> >> >>> Am 07.06.2018 um 07:29 schrieb Sven Van Caekenberghe <[hidden email]>: >>> >>> Tim, >>> >>>> On 7 Jun 2018, at 01:37, Tim Mackinnon <[hidden email]> wrote: >>>> >>>> Hi - I’ve hit some Json where the outputted values (they are field names) are written out in a specific order - and the author hasn’t chosen to use an array to represent those fields in a specific order. >>>> >>>> { ‘field1’ : { ….}, ‘field2’: { … } } >>>> >>>> I think this is technically incorrect and should be: >>>> >>>> { [ {‘field1’ : { ….}, ‘field2’: { … } ]} >>>> >>>> Anyway - given what I’ve got, would it be a terrible idea to create my own version NeoJsonObject and just make it a subclass of OrderedDictionary? >>>> >>>> I can’t see any issues - but then I might be kidding myself… >>>> >>>> Tim >>> >>> Yea, I think you could try making a NeoJSONOrderedObject as a subclass of OrderedDictionary, modelled after NeoJSONObject. Just remember it is implemented using DNU, which will surprise you at one point. >>> >> Wouldn‘t be setting #mapClass: on the reader to OrderedDictionary not enough? Dictionary is the default anyway. >> >> Norbert > > Yes, of course, Norbert, it keeps the order: > > (NeoJSONReader on: '{"BB":1,"CC":2,"AA":3}' readStream) mapClass: OrderedDictionary; next. > > => an OrderedDictionary('BB'->1 'CC'->2 'AA'->3) > > NeoJSONWriter toString: (OrderedDictionary new at: #BB put: 1; at: #CC put: 2; at: #AA put: 3; yourself). > > => '{""BB"":1,""CC"":2,""AA"":3}' > > It is not functionally 100% the same as a hypothetical NeoJSONOrderedObject, but might do. > > Sven |
> Am 07.06.2018 um 14:16 schrieb Tim Mackinnon <[hidden email]>: > > Thanks guys - it seems like I was on the right track. > > Making my own NeoJsonObject did work, but I will go back and see if I’m really using the js nature of the values and if for this, just an OrderedDictionary might be clearer. > And safer. The current implementation of NeoJSONObject is not ver good. It returns nil on any missing key so you mask a lot of errors in your code which I find dangerous. Norbert > As an aside, I was doing some experiments with prismic.io (a headless cms) and the order of your content when rendering it on a page(generically) is obviously important. > > Tim > > Sent from my iPhone > >> On 7 Jun 2018, at 07:46, Sven Van Caekenberghe <[hidden email]> wrote: >> >> >> >>> On 7 Jun 2018, at 08:16, Norbert Hartl <[hidden email]> wrote: >>> >>> >>> >>>> Am 07.06.2018 um 07:29 schrieb Sven Van Caekenberghe <[hidden email]>: >>>> >>>> Tim, >>>> >>>>> On 7 Jun 2018, at 01:37, Tim Mackinnon <[hidden email]> wrote: >>>>> >>>>> Hi - I’ve hit some Json where the outputted values (they are field names) are written out in a specific order - and the author hasn’t chosen to use an array to represent those fields in a specific order. >>>>> >>>>> { ‘field1’ : { ….}, ‘field2’: { … } } >>>>> >>>>> I think this is technically incorrect and should be: >>>>> >>>>> { [ {‘field1’ : { ….}, ‘field2’: { … } ]} >>>>> >>>>> Anyway - given what I’ve got, would it be a terrible idea to create my own version NeoJsonObject and just make it a subclass of OrderedDictionary? >>>>> >>>>> I can’t see any issues - but then I might be kidding myself… >>>>> >>>>> Tim >>>> >>>> Yea, I think you could try making a NeoJSONOrderedObject as a subclass of OrderedDictionary, modelled after NeoJSONObject. Just remember it is implemented using DNU, which will surprise you at one point. >>>> >>> Wouldn‘t be setting #mapClass: on the reader to OrderedDictionary not enough? Dictionary is the default anyway. >>> >>> Norbert >> >> Yes, of course, Norbert, it keeps the order: >> >> (NeoJSONReader on: '{"BB":1,"CC":2,"AA":3}' readStream) mapClass: OrderedDictionary; next. >> >> => an OrderedDictionary('BB'->1 'CC'->2 'AA'->3) >> >> NeoJSONWriter toString: (OrderedDictionary new at: #BB put: 1; at: #CC put: 2; at: #AA put: 3; yourself). >> >> => '{""BB"":1,""CC"":2,""AA"":3}' >> >> It is not functionally 100% the same as a hypothetical NeoJSONOrderedObject, but might do. >> >> Sven > > |
> On 7 Jun 2018, at 14:42, Norbert Hartl <[hidden email]> wrote: > > > >> Am 07.06.2018 um 14:16 schrieb Tim Mackinnon <[hidden email]>: >> >> Thanks guys - it seems like I was on the right track. >> >> Making my own NeoJsonObject did work, but I will go back and see if I’m really using the js nature of the values and if for this, just an OrderedDictionary might be clearer. >> > And safer. The current implementation of NeoJSONObject is not ver good. It returns nil on any missing key so you mask a lot of errors in your code which I find dangerous. Haha, it was modelled after a JavaScript object, of course it is worse, but more convenient in scripting code. Sure, a plain Dictionary is better. > Norbert > >> As an aside, I was doing some experiments with prismic.io (a headless cms) and the order of your content when rendering it on a page(generically) is obviously important. >> >> Tim >> >> Sent from my iPhone >> >>> On 7 Jun 2018, at 07:46, Sven Van Caekenberghe <[hidden email]> wrote: >>> >>> >>> >>>> On 7 Jun 2018, at 08:16, Norbert Hartl <[hidden email]> wrote: >>>> >>>> >>>> >>>>> Am 07.06.2018 um 07:29 schrieb Sven Van Caekenberghe <[hidden email]>: >>>>> >>>>> Tim, >>>>> >>>>>> On 7 Jun 2018, at 01:37, Tim Mackinnon <[hidden email]> wrote: >>>>>> >>>>>> Hi - I’ve hit some Json where the outputted values (they are field names) are written out in a specific order - and the author hasn’t chosen to use an array to represent those fields in a specific order. >>>>>> >>>>>> { ‘field1’ : { ….}, ‘field2’: { … } } >>>>>> >>>>>> I think this is technically incorrect and should be: >>>>>> >>>>>> { [ {‘field1’ : { ….}, ‘field2’: { … } ]} >>>>>> >>>>>> Anyway - given what I’ve got, would it be a terrible idea to create my own version NeoJsonObject and just make it a subclass of OrderedDictionary? >>>>>> >>>>>> I can’t see any issues - but then I might be kidding myself… >>>>>> >>>>>> Tim >>>>> >>>>> Yea, I think you could try making a NeoJSONOrderedObject as a subclass of OrderedDictionary, modelled after NeoJSONObject. Just remember it is implemented using DNU, which will surprise you at one point. >>>>> >>>> Wouldn‘t be setting #mapClass: on the reader to OrderedDictionary not enough? Dictionary is the default anyway. >>>> >>>> Norbert >>> >>> Yes, of course, Norbert, it keeps the order: >>> >>> (NeoJSONReader on: '{"BB":1,"CC":2,"AA":3}' readStream) mapClass: OrderedDictionary; next. >>> >>> => an OrderedDictionary('BB'->1 'CC'->2 'AA'->3) >>> >>> NeoJSONWriter toString: (OrderedDictionary new at: #BB put: 1; at: #CC put: 2; at: #AA put: 3; yourself). >>> >>> => '{""BB"":1,""CC"":2,""AA"":3}' >>> >>> It is not functionally 100% the same as a hypothetical NeoJSONOrderedObject, but might do. >>> >>> Sven >> >> > > |
On 07/06/2018 13:59, Sven Van Caekenberghe wrote:
>> On 7 Jun 2018, at 14:42, Norbert Hartl <[hidden email]> wrote: >> And safer. The current implementation of NeoJSONObject is not ver good. It returns nil on any missing key so you mask a lot of errors in your code which I find dangerous. > > Haha, it was modelled after a JavaScript object, of course it is worse, but more convenient in scripting code. > Sure, a plain Dictionary is better. Nothing that syntax sugar mapping some convenient property accessor to #at: couldn't fix. :) -- Esteban A. Maringolo |
> Am 07.06.2018 um 21:18 schrieb Esteban A. Maringolo <[hidden email]>: > > On 07/06/2018 13:59, Sven Van Caekenberghe wrote: >>> On 7 Jun 2018, at 14:42, Norbert Hartl <[hidden email]> wrote: >>> And safer. The current implementation of NeoJSONObject is not ver good. It returns nil on any missing key so you mask a lot of errors in your code which I find dangerous. >> >> Haha, it was modelled after a JavaScript object, of course it is worse, but more convenient in scripting code. >> Sure, a plain Dictionary is better. > > Nothing that syntax sugar mapping some convenient property accessor to > #at: couldn't fix. :) > > |
In reply to this post by Tim Mackinnon
The order of key:value pairs in a JSON "object" is really NOT supposed to matter. For example, if you put {"a":1,"b":2} into a JSON database you should not be surprised to get {"b":2,"a":1} back. Or vice versa, of course. On 8 June 2018 at 00:16, Tim Mackinnon <[hidden email]> wrote: Thanks guys - it seems like I was on the right track. |
But when it does what do you do? It is pretty clear that the order is important for that format. So saying it shouldn’t matter does not make it better. If you work with mongo DB you will see the same that for some queries you have to provide proper order of keys. Norbert
|
Sent from my iPhone
|
In reply to this post by NorbertHartl
Yes i was a bit nervous about the ordering, but had also noticed other examples like this - but it is a good reminder for me to double check with the developers that they consciously have done this and to register an interest that it stays that way (particularly as they strangely don’t provide access to a schema for your user type definition - and hence could get the ordering from that). On a second note - I did phase out my use of NeoJsonObject after the community warning (and realised how much it had worked into my solution). I think explicitly handling the absent key is better (I do loathe nil checks and am surprised how many languages set this terrible example - of shocked how easily I fell into that trap too). That said - I did miss the #atPath: concept in NeoJson and ended up adding an equivalent (better?) #atPath:ifAbsent: to OrderedDictionary to cope with needing to reach into structures to pull out relevant attributes. It did then remind how much I wish we could sort out some form of namespacing, as I don’t like to see my model code have to put prAtPath:ifAbsent: (it’s just gross). Maybe I might subclass OrderedDictionary to get the namespacing on a class and my methods can be safely clean). Appreciate the commentary on this, it’s been a useful exercise. Tim Sent from my iPhone
|
In reply to this post by NorbertHartl
I'm really baffled here. Look at the definition at json.org. An object is an UNORDERED set of name/value pairs. Or look at ECMA-404, which json.org points to. The JSON syntax does not impose any restrictions on the strings used as names ... and DOES NOT ASSIGN ANY SIGNIFICANCE TO THE ORDERING. When you say that "it is pretty clear that the order is important for that format" I fail to understand you. It is absolutely clear that by design the order is NOT important or even significant for JSON. JSON Pointer does not provide any way to refer to order in an "object": /2 applied to an object will look for the name "2" as a string. JSONPath does not provide any way to refer to order in an "object": [2] applied to an object will look for the name "2" as a string. JSON Schema does not provide any way to constrain or refer to order in an "object". As for databases, Postgres documentation says of JSONB that "Insignificant whitespace is discarded, and the order of object keys is not preserved." If you are communicating with someone else who is using pseudo-JSON that does attach semantics to the order of the name/value pairs, then of course you do whatever you have to in order to communicate successfully. Just don't think of it as JSON. If you have two programs whose protocol you control, again you can use JSON syntax with different semantics all you want. Just don't think of it as JSON. Heck, if it is important to you to distinguish between integer 1 and floating point 1.0, you can add your own semantics if you like, but *JSON* doesn't distinguish them. As for MongoDB, it works with BSON (which is richer than JSON. which is why "MongoDB Extended JSON exists), and does some seriously odd things, like regarding {} and {"a": null} as equal. (According to the 3.6 manual.) Do whatever you have to do to get the job done, but just remember that most JSON tools think they are dealing with *JSON*, not something else that looks like it but has different semantics, and can be relied on to preserve or respect *JSON* semantics, not some other semantics unknown to them. |
It was not talked about JSON but about a content format that uses JSON as its encoding. So if that format how poor it appears to use puts significance to the ordering why you even start to argue? Why care about JSON tools and talk about semantics because there is no semantic in an encoding format. It is an encoding format of nested keys and values and arrays. No key or value has special meaning. It is dumb JSON. You can use every JSON tool to read and destroy it. Like you can read a binary file in a text editor apply newline conventions and destroy it. What is the point here? Norbert
|
Norbert Hartl wrote on 11. 6. 2018 23:38: > > > Am 11.06.2018 um 16:48 schrieb Richard O'Keefe <[hidden email] > <mailto:[hidden email]>>: > >> I'm really baffled here. >> Look at the definition at json.org <http://json.org>. >> >> An object is an UNORDERED set of name/value pairs. >> >> Or look at ECMA-404, which json.org <http://json.org> points to. >> >> The JSON syntax does not impose any restrictions on >> the strings used as names ... and DOES NOT ASSIGN >> ANY SIGNIFICANCE TO THE ORDERING. >> >> When you say that "it is pretty clear that the order is >> important for that format" I fail to understand you. >> It is absolutely clear that by design the order is NOT >> important or even significant for JSON. >> >> JSON Pointer does not provide any way to refer to order >> in an "object": /2 applied to an object will look for >> the name "2" as a string. >> >> JSONPath does not provide any way to refer to order in >> an "object": [2] applied to an object will look for >> the name "2" as a string. >> >> JSON Schema does not provide any way to constrain or >> refer to order in an "object". >> >> As for databases, Postgres documentation says of JSONB >> that "Insignificant whitespace is discarded, and >> the order of object keys is not preserved." >> >> If you are communicating with someone else who is using >> pseudo-JSON that does attach semantics to the order of >> the name/value pairs, then of course you do whatever you >> have to in order to communicate successfully. Just don't >> think of it as JSON. If you have two programs whose >> protocol you control, again you can use JSON syntax with >> different semantics all you want. Just don't think of it >> as JSON. Heck, if it is important to you to distinguish >> between integer 1 and floating point 1.0, you can add >> your own semantics if you like, but *JSON* doesn't >> distinguish them. >> >> As for MongoDB, it works with BSON (which is richer than >> JSON. which is why "MongoDB Extended JSON exists), and >> does some seriously odd things, like regarding >> {} and {"a": null} as equal. (According to the 3.6 manual.) >> >> Do whatever you have to do to get the job done, >> but just remember that most JSON tools think they are >> dealing with *JSON*, not something else that looks >> like it but has different semantics, and can be relied >> on to preserve or respect *JSON* semantics, not some >> other semantics unknown to them. >> > It was not talked about JSON but about a content format that uses JSON > as its encoding. So if that format how poor it appears to use puts > significance to the ordering why you even start to argue? > Why care about JSON tools and talk about semantics because there is no > semantic in an encoding format. It is an encoding format of nested keys > and values and arrays. No key or value has special meaning. It is dumb > JSON. > You can use every JSON tool to read and destroy it. Like you can read a > binary file in a text editor apply newline conventions and destroy it. > What is the point here? I presume the point here is that, if you presume JSON is mostly used with JavaScript, then JSON _is_, in effect, keeping the order. If I am not mistaken, it is already part of the spec a few years already that enumeration on the object keys MUST respect the order in which keys were created, and JSON algorithm prescribes that keys are created in the order they are read when parsing, and should use the internal order of keys when stringifying. So, JSON is de facto preserving order, though de iure it is not. But the fact that is does it de facto, leads to creation of order-dependent services. Not saying this is correct per specs, not that it is correct from general design PoV, just that it happens because order preserving _is_ already there, so the code may end up using it, even unconsciously. This "JSON is in practice order-preserving" implementation artifact then leaks out when some protocols end up requiring it. Then other languages may feel the need to have this "industry standard" of order-preserving JSON to have as well. OP correct me if I am wrong. Herby > Norbert |
Herbert Vojčík wrote " it is already part of the spec a few years already that enumeration on the object keys MUST respect the order in which keys were created". I quoted two specs: json.org and the ECMA one. The current RFC for JSON is, I believe, RFC 8259, which says JSON parsing libraries have been observed to differ as to whether or not they make the ordering of object members visible to calling software. Implementations whose behavior does not depend on member ordering will be interoperable in the sense that they will not be affected by these differences. What this is saying is that some JSON libraries do preserve order and some do NOT. There is no "de facto" standard specifying order preservation. What's more, the language is warning you that if you rely on order, you should NOT expect your program to interoperate with anything else and it is your fault if it doesn't. If there is some other specification for JSON that requires order to be preserved, tell us where to find it. This is not about JavaScript. JSON is not strictly compatible with JavaScript anyway. Consider Python: >>> json.loads('{"a":1,"b":2}') {u'a': 1, u'b': 2} >>> json.loads('{"b":2,"a":1}') {u'a': 1, u'b': 2} Using JSON::Parse in Perl gives the same result; the order does not matter. I could go on all day listing JSON libraries, tools, and interfaces that either never preserve key order or make that an esoteric use- at-your-own-peril option. When you are designing a protocol using JSON syntax, and you want an ordered association between keys and values, you can interoperably use something like { "__isOrderedObject__": true , "keys": ["a","b"] , "values": [1, 2 ] } Just to repeat: if you can find any ISO, ECMA, ITU, or IETF specification that says key order should be preserved, let's hear about it. I have three JSON parsers I've written, and I want them to be right. Not like the brand X package that says it can sometimes fail to read back JSON that it wrote. |
Richard O'Keefe wrote on 12. 6. 2018 3:54: > > Herbert Vojčík > > wrote " it is already part of the spec a few years already that > enumeration on the object keys MUST respect the order in which keys > were created". The JavaScript (ECMA-262) spec, not the JSON (ECMA 404) spec. The rest follows as described in my previous post. |
In reply to this post by Tim Mackinnon
Once again, thanks for the interesting background to all of this (although I didn’t mean to cause so much discussion on the merits of the json spec).
Anyway, I did check with the authors of Prismic.io - and they confirmed that their intent is that their document (schema?) does order block elements in the json - and this is something you can rely on. So, its not really in my control to do otherwise. Tim
|
Free forum by Nabble | Edit this page |