Tom Sawyer [09/09/02 15:26 -0600]:
> essentially i believe yaml should cover the fundemental possibilites,
> and do so elegently. otherwise you leave a large set use cases out in
> the cold. do we really want those users to go off and create ZAYML? ;-)
> i hope not, so lets just provide for their needs too!
I admit I've only skimmed over most of the messages from this weekend, but I
have to say I don't understand the fuss over ordered keys and stuff like
that. A decent YAML implementation should expose any layer you want; so if
you want ordered keys, then use the layer at which they're exposed. You
should also be able to use parts of multiple layers *at the same time*.
Here's a neat YAML application that I recently would have *loved* to use:
Load a commented (YAML) config file, preserving user comments. Then
pretty print it, splitting out parts of the config file to different
files. While at it, sort the keys alphabetically, except comment
keys, which should be sorted so that comment key always appears
before the same node as in the original file.
Does that make sense? So here's a tiny example of the input:
--- #YAML:1.0
# The maximum number of interpreters to run
max_concurrent: 64
# The number of interpreters to preinitialize on startup
preinit: 15
# The maximum number of sessions to serve per interpreter
max_sessions: 2048
# This section gives options for the "foo" application
applications:
foo:
root: /opt/xxx/etc/data/foo
//nice: 0 # how nice to make these interpreters?
conf: /opt/xxx/etc/conf/foo
The input file might come from config.yaml; the output should go to
config.yaml and config.d/foo.yaml. Make sense?
[Note that although I don't care about the actual order of keys in my
problem, I do care about the relative order. A comment must appear next
to the same node as it did in the input, although the nodes nearby might be
different. Also, I want to preserve "throwaway" comments, so I have to have
the parser tell me about them in such a way that I can bind them into my
parse tree.]
Here's one way to solve the problem: use the *parser*, not the loader. The
parser always keeps the node order, because it parses them from a stream,
which is by definition ordered. However, I also want to construct a nice
parse tree so I don't have to build it up myself, so I should be able to use
the loader as well, and tell it to use my parser. Here's how I'd set it all
up in Perl (one day):
my $parser = YAML::Parser->new(preserve_throwaways => 1);
my $loader = YAML::Loader->new(parser => $parser,
binding => 'generic',
);
my $dumper = YAML::Dumper->new;
my $tree = $loader->load("config.yaml");
my @conf_files;
# At this point, one wishes YPATH exists:
# $tree->select("/children//"); # or however I do that :)
for my $key ($tree->children) {
next unless $key->val eq 'applications';
my $apps = $key;
$tree->prune($key); # not for you anymore, $tree!
for my $app ($apps->children) {
push @conf_files, $app;
$apps->prune($app);
}
}
# Plug in my own sort{} method (LAAEFTR):
$dumper->sortkeys(sub { ... });
# Write back the various config files:
$dumper->dumpfile($tree, "config.yaml");
for my $conf (@conf_files) {
$dumper->dumpfile($conf, $conf->name . ".yaml");
}
In other words, I preserved comments and key order (sometimes) but I paid a
slight price.
I guess I want to know this. Are people worried that:
(a) the above solution is way too complicated.
If so, you've obviously never used XML. This is *really* simple. And
I just made it up; goodness knows how much more the libraries might do
for you!
(b) the above solution won't work.
I'm sure the authors will allow users access to various layers of
YAML. They have to! Otherwise no one will be able to write nice tools;
not every tool can work at the native layer, as we all know.
(c) "But I just want to preserve key order."
Fine! Your code is simpler than mine, then. My code had to sort the
keys -- yours won't!
I'd love to know where people are confused. Maybe this will help.
Thanks,
Neil
|