From: William S. <sp...@rh...> - 2009-08-25 16:51:49
|
A much more interesting question about yaml: I doubt we are unique in that the data we wish to store is an array of objects, all of them are different subclasses of some base object, and the fields of these subclasses are different, and "which subclass" is not predictable. What I propose to do to write an array containing them like this (where both classes have a 'name' field, but class A has an 'a' field and class B has a 'b' field: - !A {name: nameofa, a: value of a} - !B {name: nameofb, b: value of b} - !A {name: nameofa2, a: value} ... Is this the planned usage of the type tags? Note that the 'b' field will produce an error if placed in the A object. Another post here suggested this: - {type: A, name: nameofa, a: value of a} - {type: B, name: nameofb, b: value of b} - {type: A, name: nameofa2, a: value} ... However this seems to require that "type" be first, at least if we want to read directly into the object, rather than have to make a temporary name+value structure and then set the object after I get the type. Obviously I can force the yaml file to have the type first but this seems inconsistent with yaml's design. Am I using it as intended? Any other alternatives I missed? One thing that attracted me to yaml was this tagging, which json lacks, because it looked like the correct way to do this. Bill Spitzak Rhythm & Hues software dept |
From: Oren Ben-K. <or...@be...> - 2009-08-25 21:09:31
|
On Tue, 2009-08-25 at 09:51 -0700, William Spitzak wrote: > A much more interesting question about yaml: > > I doubt we are unique in that the data we wish to store is an array of > objects, all of them are different subclasses of some base object, and > the fields of these subclasses are different, and "which subclass" is > not predictable. > > What I propose to do to write an array containing them like this (where > both classes have a 'name' field, but class A has an 'a' field and class > B has a 'b' field: > > - !A {name: nameofa, a: value of a} > - !B {name: nameofb, b: value of b} > - !A {name: nameofa2, a: value} > ... > > Is this the planned usage of the type tags? Note that the 'b' field will > produce an error if placed in the A object. Yes, this makes perfect sense. Of course you have another option: look in the hash table and decide whether to load it to an A or a B depending on whether you see an 'a' key or a 'b' key. The details on how to do that depend on the specific YAML library used, and you _will_ need to create a temporary hash table, but this is explicitly allowed by the spec. > Another post here suggested this: > > - {type: A, name: nameofa, a: value of a} > - {type: B, name: nameofb, b: value of b} > - {type: A, name: nameofa2, a: value} > ... > > However this seems to require that "type" be first, at least if we want > to read directly into the object, rather than have to make a temporary > name+value structure and then set the object after I get the type. > Obviously I can force the yaml file to have the type first but this > seems inconsistent with yaml's design. In general you can't force, or rely on, the order of the keys in the file. That is, in general someone may apply some tool to the file (say a pretty-printer) that will sort the keys alphabetically, or something, and then you'd be SOL. Using tags as in the previous example is the recommended way. Or, you may accept the overhead of creating the temporary structure. > Am I using it as intended? Any other alternatives I missed? Nope, these are pretty much the two options you have. Tags or temporary structure. Actually... you _could_ mess up the file structure and do something like: - a: { name: nameofa, a: value of a } - b: { name: nameofb, b: value of b } But that's really just a dirtier form of tagging. Have fun, Oren Ben-Kiki |
From: William S. <sp...@rh...> - 2009-08-26 01:02:10
|
Oren Ben-Kiki wrote: > In general you can't force, or rely on, the order of the keys in the > file. That is, in general someone may apply some tool to the file (say a > pretty-printer) that will sort the keys alphabetically, or something, > and then you'd be SOL. Using tags as in the previous example is the > recommended way. Or, you may accept the overhead of creating the > temporary structure. Yes this is what I figured. I am using the parser/emitter api to libyaml and I certainly do not want any temporary object, both because of the overhead and because it will throw errors in different than lexical order from the file. > you _could_ mess up the file structure and do > something like: > > - a: { name: nameofa, a: value of a } > - b: { name: nameofb, b: value of b } > > But that's really just a dirtier form of tagging. I guess that would work. It has the advantage that it works in json (though it looks ugly there), while if I use tags I will never be able to produce legit json. Anyway I currently plan on using the tags. |
From: William S. <sp...@rh...> - 2009-08-27 17:54:11
|
Oren Ben-Kiki wrote: >> - !A {name: nameofa, a: value of a} >> - !B {name: nameofb, b: value of b} >> - !A {name: nameofa2, a: value} >> ... > Of course you have another option: look > in the hash table and decide whether to load it to an A or a B depending > on whether you see an 'a' key or a 'b' key. I think I did not explain the problem right, the keys don't determine the class, it is just that some classes have different keys than others. We also have different classes with identical keys. Now looking at the output for the non-tagged version, I'm starting to be happier with the !tag output, despite the json incompatibility. In particular the default indentation is nicer. |
From: William S. <sp...@rh...> - 2009-09-29 17:13:53
|
Just to follow up, we are using tags. A big advantage so far is that the tag is optional and it is easy to ignore it when reading. This allows further compression by omitting the tag when the reader knows the type, which happens a lot, but it is still ok if the writer wrote the tag. This proposal: >>> - a: { name: nameofa, a: value of a } >>> - b: { name: nameofb, b: value of b } seems a little strange in that it looks like a list of objects with one member for each type. If the second '-' was not there it would be setting both the 'a' and 'b' members and a yaml validator would think this is ok. It is nice that this can be stored as JSON but I have given up on that. I think the description of tag syntax is confused in the YAML documentation. Would prefer that the leading '!' be considered a token indicating a tag and the tag itself be the rest of the string (including any further '!' characters). I believe this matches much more how people use it. For instance I certainly store all my local tags with no '!' in them. Bill Spitzak Rhythm & Hues |
From: Oren Ben-K. <or...@be...> - 2009-09-30 05:33:24
|
On Tue, 2009-09-29 at 10:13 -0700, William Spitzak wrote: > Just to follow up, we are using tags. > > A big advantage so far is that the tag is optional and it is easy to > ignore it when reading. This allows further compression by omitting the > tag when the reader knows the type, which happens a lot, but it is still > ok if the writer wrote the tag. > > This proposal: > > >>> - a: { name: nameofa, a: value of a } > >>> - b: { name: nameofb, b: value of b } > > seems a little strange in that it looks like a list of objects with one > member for each type. It is exactly that: a list of mappings, each with a single key, and a value which is a mapping with two keys (name and an additional one). > If the second '-' was not there it would be > setting both the 'a' and 'b' members and a yaml validator would think > this is ok. If there was no second '-' it would be a list of objects with one entry; that entry would be a mapping with two keys. Both of these are very different from a list containing two entries, each being a tagged mapping with two keys (name and an additional one). > I think the description of tag syntax is confused in the YAML > documentation. Would prefer that the leading '!' be considered a token > indicating a tag and the tag itself be the rest of the string (including > any further '!' characters). I believe this matches much more how people > use it. For instance I certainly store all my local tags with no '!' in > them. I think you are ascribing some magic to your example syntax that does not actually occur. Tags are very different from mapping keys. Have fun, Oren Ben-Kiki |
From: William S. <sp...@rh...> - 2009-08-27 17:42:46
|
> Oren Ben-Kiki wrote: >> you _could_ mess up the file structure and do >> something like: >> >> - a: { name: nameofa, a: value of a } >> - b: { name: nameofb, b: value of b } >> >> But that's really just a dirtier form of tagging. > > I guess that would work. It has the advantage that it works in json > (though it looks ugly there), while if I use tags I will never be able > to produce legit json. Actually after a bit of work I decided we should use this second method. The primary reason is that I can losslessly convert to json. Also libyaml had some strange ideas about exclamation points that made me think I might be using tags incorrectly, while names were done cleanly. |