Chris Muller uploaded a new version of JSON to project The Trunk: http://source.squeak.org/trunk/JSON-cmm.61.mcz
==================== Summary ====================
Name: JSON-cmm.61 Author: cmm Time: 18 February 2024, 6:01:50.22946 pm UUID: 9f100ce1-3d3c-4ea2-b975-4821175b41ba Ancestors: JSON-ct.58
Path access and enumeration for JSON objects.
=============== Diff against JSON-ct.58 ===============
Item was added: + ----- Method: Collection>>atPath: (in category '*json') ----- + atPath: anArray + "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray." + ^ self + atPath: anArray + ifLost: [ : last | self error: 'path lost after' , last asString ]!
Item was added: + ----- Method: Collection>>atPath:ifLost: (in category '*json') ----- + atPath: anArray ifLost: aBlock + "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray. If the full path specified by anArray isn't present, cull aBlock with the last element present along the path." + | last | + ^ (self + path: anArray + do: [ : elem : node | last := node ]) + ifNil: [ aBlock cull: last ] + ifNotNil: [ last ]!
Item was added: + ----- Method: Collection>>path:do: (in category '*json') ----- + path: anArray do: aBlock + "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Value aBlock with each object along the path of indices and/or keys identified in anArray. If a path element isn't found, stop, and return nil, otherwise, return self." + anArray + inject: self + into: + [ : dictOrArray : pathElem | dictOrArray + at: pathElem + ifPresent: [ : node | aBlock value: pathElem value: node ] + ifAbsent: [ ^ nil ] ]. + ^ self!
Hi Chris,
I find the implementation rather unusual (e.g. the way #inject:into: is used there) and a bit too complicated (many assumptions about what returns what). #path:do: does not work correctly on its own as it relies on the argument block's return value. E.g.:
#((1)) path: #(1 1) do: [ :path :node | ] "=> DNU"
There's also some unexpected behavior:
#('foo') atPath: #(1 1) "=> $f"
I'm not sure these should be available for all collections considering all those assumptions in the method comments. Perhaps a custom class or the class side of Json would be a better place.
Best, Levente
On 2024. 02. 19. 0:01, commits@source.squeak.org wrote:
Chris Muller uploaded a new version of JSON to project The Trunk: http://source.squeak.org/trunk/JSON-cmm.61.mcz
==================== Summary ====================
Name: JSON-cmm.61 Author: cmm Time: 18 February 2024, 6:01:50.22946 pm UUID: 9f100ce1-3d3c-4ea2-b975-4821175b41ba Ancestors: JSON-ct.58
Path access and enumeration for JSON objects.
=============== Diff against JSON-ct.58 ===============
Item was added:
- ----- Method: Collection>>atPath: (in category '*json') -----
- atPath: anArray
- "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray."
- ^ self
atPath: anArray
ifLost: [ : last | self error: 'path lost after' , last asString ]!
Item was added:
- ----- Method: Collection>>atPath:ifLost: (in category '*json') -----
- atPath: anArray ifLost: aBlock
- "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray. If the full path specified by anArray isn't present, cull aBlock with the last element present along the path."
- | last |
- ^ (self
path: anArray
do: [ : elem : node | last := node ])
ifNil: [ aBlock cull: last ]
ifNotNil: [ last ]!
Item was added:
- ----- Method: Collection>>path:do: (in category '*json') -----
- path: anArray do: aBlock
- "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Value aBlock with each object along the path of indices and/or keys identified in anArray. If a path element isn't found, stop, and return nil, otherwise, return self."
- anArray
inject: self
into:
[ : dictOrArray : pathElem | dictOrArray
at: pathElem
ifPresent: [ : node | aBlock value: pathElem value: node ]
ifAbsent: [ ^ nil ] ].
- ^ self!
This are some strange methods where I have no Idea how they relate to the JSON package in the first place o.O
-t
On 23. Feb 2024, at 00:33, leves leves@caesar.elte.hu wrote:
Hi Chris,
I find the implementation rather unusual (e.g. the way #inject:into: is used there) and a bit too complicated (many assumptions about what returns what). #path:do: does not work correctly on its own as it relies on the argument block's return value. E.g.:
#((1)) path: #(1 1) do: [ :path :node | ] "=> DNU"
There's also some unexpected behavior:
#('foo') atPath: #(1 1) "=> $f"
I'm not sure these should be available for all collections considering all those assumptions in the method comments. Perhaps a custom class or the class side of Json would be a better place.
Best, Levente
On 2024. 02. 19. 0:01, commits@source.squeak.org wrote:
Chris Muller uploaded a new version of JSON to project The Trunk: http://source.squeak.org/trunk/JSON-cmm.61.mcz ==================== Summary ==================== Name: JSON-cmm.61 Author: cmm Time: 18 February 2024, 6:01:50.22946 pm UUID: 9f100ce1-3d3c-4ea2-b975-4821175b41ba Ancestors: JSON-ct.58 Path access and enumeration for JSON objects. =============== Diff against JSON-ct.58 =============== Item was added:
- ----- Method: Collection>>atPath: (in category '*json') -----
- atPath: anArray
- "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray."
- ^ self
- atPath: anArray
- ifLost: [ : last | self error: 'path lost after' , last asString ]!
Item was added:
- ----- Method: Collection>>atPath:ifLost: (in category '*json') -----
- atPath: anArray ifLost: aBlock
- "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray. If the full path specified by anArray isn't present, cull aBlock with the last element present along the path."
- | last |
- ^ (self
- path: anArray
- do: [ : elem : node | last := node ])
- ifNil: [ aBlock cull: last ]
- ifNotNil: [ last ]!
Item was added:
- ----- Method: Collection>>path:do: (in category '*json') -----
- path: anArray do: aBlock
- "Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Value aBlock with each object along the path of indices and/or keys identified in anArray. If a path element isn't found, stop, and return nil, otherwise, return self."
- anArray
- inject: self
- into:
- [ : dictOrArray : pathElem | dictOrArray
- at: pathElem
- ifPresent: [ : node | aBlock value: pathElem value: node ]
- ifAbsent: [ ^ nil ] ].
- ^ self!
Hi Levente,
Thank you for the review. I went back and did it right, taking into account all of your feedback (although not every suggestion), one additional feature I need, and a couple of tests.
Best Regards, Chris
On Thu, Feb 22, 2024 at 5:33 PM leves leves@caesar.elte.hu wrote:
Hi Chris,
I find the implementation rather unusual (e.g. the way #inject:into: is used there) and a bit too complicated (many assumptions about what returns what). #path:do: does not work correctly on its own as it relies on the argument block's return value. E.g.:
#((1)) path: #(1 1) do: [ :path :node | ] "=> DNU"
There's also some unexpected behavior:
#('foo') atPath: #(1 1) "=> $f"
I'm not sure these should be available for all collections considering all those assumptions in the method comments. Perhaps a custom class or the class side of Json would be a better place.
Best, Levente
On 2024. 02. 19. 0:01, commits@source.squeak.org wrote:
Chris Muller uploaded a new version of JSON to project The Trunk: http://source.squeak.org/trunk/JSON-cmm.61.mcz
==================== Summary ====================
Name: JSON-cmm.61 Author: cmm Time: 18 February 2024, 6:01:50.22946 pm UUID: 9f100ce1-3d3c-4ea2-b975-4821175b41ba Ancestors: JSON-ct.58
Path access and enumeration for JSON objects.
=============== Diff against JSON-ct.58 ===============
Item was added:
- ----- Method: Collection>>atPath: (in category '*json') -----
- atPath: anArray
"Assume I'm a set of nested HashedCollections and/or
SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray."
^ self
atPath: anArray
ifLost: [ : last | self error: 'path lost after' , last
asString ]!
Item was added:
- ----- Method: Collection>>atPath:ifLost: (in category '*json') -----
- atPath: anArray ifLost: aBlock
"Assume I'm a set of nested HashedCollections and/or
SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray. If the full path specified by anArray isn't present, cull aBlock with the last element present along the path."
| last |
^ (self
path: anArray
do: [ : elem : node | last := node ])
ifNil: [ aBlock cull: last ]
ifNotNil: [ last ]!
Item was added:
- ----- Method: Collection>>path:do: (in category '*json') -----
- path: anArray do: aBlock
"Assume I'm a set of nested HashedCollections and/or
SequenceableCollections. Value aBlock with each object along the path of indices and/or keys identified in anArray. If a path element isn't found, stop, and return nil, otherwise, return self."
anArray
inject: self
into:
[ : dictOrArray : pathElem | dictOrArray
at: pathElem
ifPresent: [ : node | aBlock value:
pathElem value: node ]
ifAbsent: [ ^ nil ] ].
^ self!
Hi Chris
On 24. Feb 2024, at 08:27, Chris Muller asqueaker@gmail.com wrote:
Hi Levente,
Thank you for the review. I went back and did it right, taking into account all of your feedback (although not every suggestion), one additional feature I need, and a couple of tests.
I still fail to see why this specific DSL is good for general use, AND why it should be in the JSON package. There's nothing very JSONy in this path-notion.
ON that note: There's now a JSONPath spec, which is just now an Internet Standard: https://www.rfc-editor.org/rfc/rfc9535.html
Maybe that's a more specific "knife" to cut things with?
Best regards -Tobias
Best Regards, Chris
On Thu, Feb 22, 2024 at 5:33 PM leves leves@caesar.elte.hu wrote: Hi Chris,
I find the implementation rather unusual (e.g. the way #inject:into: is used there) and a bit too complicated (many assumptions about what returns what). #path:do: does not work correctly on its own as it relies on the argument block's return value. E.g.:
#((1)) path: #(1 1) do: [ :path :node | ] "=> DNU"
There's also some unexpected behavior:
#('foo') atPath: #(1 1) "=> $f"
I'm not sure these should be available for all collections considering all those assumptions in the method comments. Perhaps a custom class or the class side of Json would be a better place.
Best, Levente
On 2024. 02. 19. 0:01, commits@source.squeak.org wrote:
Chris Muller uploaded a new version of JSON to project The Trunk: http://source.squeak.org/trunk/JSON-cmm.61.mcz
==================== Summary ====================
Name: JSON-cmm.61 Author: cmm Time: 18 February 2024, 6:01:50.22946 pm UUID: 9f100ce1-3d3c-4ea2-b975-4821175b41ba Ancestors: JSON-ct.58
Path access and enumeration for JSON objects.
=============== Diff against JSON-ct.58 ===============
Item was added:
- ----- Method: Collection>>atPath: (in category '*json') -----
- atPath: anArray
"Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray."
^ self
atPath: anArray
ifLost: [ : last | self error: 'path lost after' , last asString ]!
Item was added:
- ----- Method: Collection>>atPath:ifLost: (in category '*json') -----
- atPath: anArray ifLost: aBlock
"Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray. If the full path specified by anArray isn't present, cull aBlock with the last element present along the path."
| last |
^ (self
path: anArray
do: [ : elem : node | last := node ])
ifNil: [ aBlock cull: last ]
ifNotNil: [ last ]!
Item was added:
- ----- Method: Collection>>path:do: (in category '*json') -----
- path: anArray do: aBlock
"Assume I'm a set of nested HashedCollections and/or SequenceableCollections. Value aBlock with each object along the path of indices and/or keys identified in anArray. If a path element isn't found, stop, and return nil, otherwise, return self."
anArray
inject: self
into:
[ : dictOrArray : pathElem | dictOrArray
at: pathElem
ifPresent: [ : node | aBlock value: pathElem value: node ]
ifAbsent: [ ^ nil ] ].
^ self!
Hi Tobias,
I'm not sure if you answered your own question, or whether you plan to pose it to the IETF, but for me #pathAt: is for the same use-case as Dictionary>>#at:, except for multilevel aggregated Dictionary's, e.g., Json outputs. JSONPath is a text-based query language with that capability and more for putting some application logic in the DSL. If you decide to implement it, Collection>>#path:do: will likely be a core foundational method you'll need to execute those query's.
Regards, Chris
On Sat, Feb 24, 2024 at 1:59 AM Tobias Pape via Squeak-dev < squeak-dev@lists.squeakfoundation.org> wrote:
Hi Chris
On 24. Feb 2024, at 08:27, Chris Muller asqueaker@gmail.com wrote:
Hi Levente,
Thank you for the review. I went back and did it right, taking into
account all of your feedback (although not every suggestion), one additional feature I need, and a couple of tests.
I still fail to see why this specific DSL is good for general use, AND why it should be in the JSON package. There's nothing very JSONy in this path-notion.
ON that note: There's now a JSONPath spec, which is just now an Internet Standard: https://www.rfc-editor.org/rfc/rfc9535.html
Maybe that's a more specific "knife" to cut things with?
Best regards -Tobias
Best Regards, Chris
On Thu, Feb 22, 2024 at 5:33 PM leves leves@caesar.elte.hu wrote: Hi Chris,
I find the implementation rather unusual (e.g. the way #inject:into: is used there) and a bit too complicated (many assumptions about what returns what). #path:do: does not work correctly on its own as it relies on the argument block's return value. E.g.:
#((1)) path: #(1 1) do: [ :path :node | ] "=> DNU"
There's also some unexpected behavior:
#('foo') atPath: #(1 1) "=> $f"
I'm not sure these should be available for all collections considering all those assumptions in the method comments. Perhaps a custom class or the class side of Json would be a better place.
Best, Levente
On 2024. 02. 19. 0:01, commits@source.squeak.org wrote:
Chris Muller uploaded a new version of JSON to project The Trunk: http://source.squeak.org/trunk/JSON-cmm.61.mcz
==================== Summary ====================
Name: JSON-cmm.61 Author: cmm Time: 18 February 2024, 6:01:50.22946 pm UUID: 9f100ce1-3d3c-4ea2-b975-4821175b41ba Ancestors: JSON-ct.58
Path access and enumeration for JSON objects.
=============== Diff against JSON-ct.58 ===============
Item was added:
- ----- Method: Collection>>atPath: (in category '*json') -----
- atPath: anArray
"Assume I'm a set of nested HashedCollections and/or
SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray."
^ self
atPath: anArray
ifLost: [ : last | self error: 'path lost after' , last
asString ]!
Item was added:
- ----- Method: Collection>>atPath:ifLost: (in category '*json') -----
- atPath: anArray ifLost: aBlock
"Assume I'm a set of nested HashedCollections and/or
SequenceableCollections. Answer the object at the path of indices and/or keys identified in anArray. If the full path specified by anArray isn't present, cull aBlock with the last element present along the path."
| last |
^ (self
path: anArray
do: [ : elem : node | last := node ])
ifNil: [ aBlock cull: last ]
ifNotNil: [ last ]!
Item was added:
- ----- Method: Collection>>path:do: (in category '*json') -----
- path: anArray do: aBlock
"Assume I'm a set of nested HashedCollections and/or
SequenceableCollections. Value aBlock with each object along the path of indices and/or keys identified in anArray. If a path element isn't found, stop, and return nil, otherwise, return self."
anArray
inject: self
into:
[ : dictOrArray : pathElem | dictOrArray
at: pathElem
ifPresent: [ : node | aBlock value:
pathElem value: node ]
ifAbsent: [ ^ nil ] ].
^ self!
squeak-dev@lists.squeakfoundation.org