std.data.json formal review

Sönke Ludwig via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 30 01:26:00 PDT 2015


Am 29.07.2015 um 11:58 schrieb Andrea Fontana:
> On Wednesday, 29 July 2015 at 08:55:20 UTC, Sönke Ludwig wrote:
>> That would be another possibility. What do you think about the
>> opt(jv).foo.bar[12].baz alternative? One advantage is that it could
>> work without parsing a string and the implications thereof (error
>> handling?).
>
> I implemented it too, but I removed.
> Many times fields name are functions name or similar and it breaks the
> code.

In this case, since it would be a separate type, there are no static 
members apart from the automatically generated ones and maybe something 
like opIndex/opAssign. It can of course also overload opIndex with a 
string argument, so that there is a generic alternative in case of 
conflicts or runtime key names.

> In my implementation it creates a lot of temporary objects (one for each
> subobj) using the string instead, i just create the last one.

If the temporary objects are cheap, I don't see an issue there. Without 
keeping track of the path, a simple pointer to a JSONValue should be 
sufficient (the temporary objects have to be made non-copyable).

>
> It's not easy for me to use assignments with that syntax. Something like:
>
> obj.with.a.new.field = 3;
>
> It's difficult to implement. It's much easier to implement:
>
> obj["/field/doesnt/exists"] = 3

Maybe more difficult, but certainly possible. If the complexity doesn't 
explode, I'd say that shouldn't be a primary concern, since this is all 
still pretty simple.

> It's much easier to write formatted-string paths.
> It allows future implementation of something like xpath/jquery style

Advanced path queries could indeed be interesting, possibly even more 
interesting if applied to the pull parser.

> If your json contains keys with "/" inside, you can still use old plain
> syntax...

A possible alternative would be to support some kind of escape syntax.

> String parsing it's quite easy (at compile time too) of course. If a
> part of path doesn't exists it works like a part of opt("a", "b", "c")
> doesn't. It's just syntax sugar. :)

Granted, it's not really much in this case, but you do get less static 
checking, which means that some things will only be caught at run time. 
Also, you'll get an ambiguity if you want to support array indices, too. 
Finally, it may even be security relevant, because an attacker might try 
to sneak in a key that contains slash characters to access/overwrite 
fields that would normally not be possible. So every user input that may 
end up in a path query will have to be validated first now.

> Does it works? Anyway it seems ambiguous:
> opt(...) == null   => false
> opt(...).isNull    => true

The former gets forwarded to Algebraic, while the latter is a method of 
the enclosing Nullable. I've tested it and it works. But I also agree it 
isn't particularly pretty in this case, but that's what we have in D as 
basic building blocks (or do we have an Optional type somewhere, yet).

>> The other possible approach, which would be more convenient to use,
>> would be add a "default value" overload to "opt", for example:
>> jv.opt("defval").foo.bar
>
> Isn't jv.opt("defval") taking the value of ("defval") rather than
> setting a default value?
>

It would be an opt with different semantics, just a theoretical 
alternative. This behavior would be mutually exclusive to the current opt.


More information about the Digitalmars-d mailing list