Hey! Thank you very much for feedback. I've applied most of the suggested changes. As for the lfun::create() approach to object deserializing - I've been thinking about it, but it's troublesome for some edge cases, like arrays and tuples.
czw., 17 sty 2019 o 18:56 Henrik Grubbström (Lysator) @ Pike (-) developers forum 10353@lyskom.lysator.liu.se napisał(a):
Hi.
I came to the point where I spent so much time on providing Pike support for QuickType, that I'd probably manage to manually write DAP and LSP
pmods
by now. So I've decided to stop there and deliver it as-is. Despite the generated code's likely poor performance, it's been thoroughly tested and proven to work for most test cases both for JSON, and JSON Schema.
I really, really wanted to reuse Standards.JSON API, or else I would wind up rewriting the whole JSON serialization module. That's why I ended up calling JSON.encode, which invokes the encoded object's encode_json
method,
inside JSON.decode. It's necessary because Pike member names are not necessary JSON's keys. For exmaple, 'else' is a perfectly valid key name
in
JSON, while it's a reserved keyword in many programming languages. QuickType has it's ways to handle such situations. Another known blunder is that it tends to append member declarations with 'mixed' when rendering from JSON Schemas. It's likely related to how QuickType handles Schema's optional properties. Here you can play around with it: https://app.quicktype.io/#l=pike
Hmm... From the JSON example:
| #define TO_MIXED(x) Standards.JSON.decode(Standards.JSON.encode(x))
Why do the above? Under normal circumstances it should be a (slow) no-op (at least when it is called from encode_json()).
[...] | string encode_json() { | mapping(string:mixed) json = ([]); | | json["greeting"] = TO_MIXED(greeting); | json["instructions"] = TO_MIXED(instructions);
More efficient would be to create the mapping inline:
string encode_json() { mapping(string:mixed) json = ([ "greeting": TO_MIXED(greeting), "instructions": TO_MIXED(instructions), ]);
[...] | Welcome Welcome_from_JSON(mixed json) {
Why is json declared mixed above?
| Welcome retval = Welcome(); | | retval.greeting = json["greeting"]; | retval.instructions = json["instructions"]; | | return retval; | }
I'd prefer having an lfun::create() in the Welcome class, that knows how to initialize from the mapping.
protected void create(mapping(string:mixed)|void json) { if (!json) return; greeting = json["greeting"]; instructions = json["instructions"]; }
... Welcome Welcome_from_JSON(mapping(string:mixed) json) { return Welcome(json); }
/grubba
Hi-
I haven't had a chance to look at the latest code, but I'm hoping to have some time this week to try this out with some real world examples.
One thing to mention is that other languages have conventions for setter and getters (ie, the JavaBeans API) and/or often use annotations to note mapping peculiarities or preferences, and this handles the bulk of the parsing customization required. For the rest, the equivalent of decode_json() would be used, but there remains the problem of mapping a bit of JSON to a class so that setters/annotations/decode_json() can be applied.
I don't think it's a problem extending the JSON parser if we can come up with a reasonable proposal for how things ought to work.
Bill
January 20, 2019 6:55 PM, "Mateusz Krawczuk" <krawczukmat@gmail.com (mailto:%22Mateusz%20Krawczuk%22%20krawczukmat@gmail.com)> wrote: Hey! Thank you very much for feedback. I've applied most of the suggested changes. As for the lfun::create() approach to object deserializing - I've been thinking about it, but it's troublesome for some edge cases, like arrays and tuples. czw., 17 sty 2019 o 18:56 Henrik Grubbström (Lysator) @ Pike (-) developers forum <10353@lyskom.lysator.liu.se (mailto:10353@lyskom.lysator.liu.se)> napisał(a): Hi.
I came to the point where I spent so much time on providing Pike support for QuickType, that I'd probably manage to manually write DAP and LSP pmods by now. So I've decided to stop there and deliver it as-is. Despite the generated code's likely poor performance, it's been thoroughly tested and proven to work for most test cases both for JSON, and JSON Schema.
I really, really wanted to reuse Standards.JSON API, or else I would wind up rewriting the whole JSON serialization module. That's why I ended up calling JSON.encode, which invokes the encoded object's encode_json method, inside JSON.decode. It's necessary because Pike member names are not necessary JSON's keys. For exmaple, 'else' is a perfectly valid key name in JSON, while it's a reserved keyword in many programming languages. QuickType has it's ways to handle such situations. Another known blunder is that it tends to append member declarations with 'mixed' when rendering from JSON Schemas. It's likely related to how QuickType handles Schema's optional properties. Here you can play around with it: https://app.quicktype.io/#l=pike (https://app.quicktype.io/#l=pike)
Hmm... From the JSON example:
| #define TO_MIXED(x) Standards.JSON.decode(Standards.JSON.encode(x))
Why do the above? Under normal circumstances it should be a (slow) no-op (at least when it is called from encode_json()).
[...] | string encode_json() { | mapping(string:mixed) json = ([]); | | json["greeting"] = TO_MIXED(greeting); | json["instructions"] = TO_MIXED(instructions);
More efficient would be to create the mapping inline:
string encode_json() { mapping(string:mixed) json = ([
"greeting": TO_MIXED(greeting), "instructions": TO_MIXED(instructions), ]);
[...] | Welcome Welcome_from_JSON(mixed json) {
Why is json declared mixed above?
| Welcome retval = Welcome(); | | retval.greeting = json["greeting"]; | retval.instructions = json["instructions"]; | | return retval; | }
I'd prefer having an lfun::create() in the Welcome class, that knows how to initialize from the mapping.
protected void create(mapping(string:mixed)|void json) { if (!json) return; greeting = json["greeting"]; instructions = json["instructions"]; } ... Welcome Welcome_from_JSON(mapping(string:mixed) json) { return Welcome(json); }
/grubba
pike-devel@lists.lysator.liu.se