Closed GoogleCodeExporter closed 9 years ago
"true" isn't a valid integer value. See
http://www.yaml.org/spec/1.2/spec.html#id2803828
If you want to convert it to 0 or 1, then
int x = node.as<bool>();
should work fine.
Original comment by jbe...@gmail.com
on 10 Jun 2013 at 8:24
as implies conversion operation... find me a language that doesn't support
casting a boolean to an integer, it's ubiquitous.
My specific problem is I'm using it with a parameter that most of the time is a
boolean but has additional functionality when using integer values. So reading
it as an int covers all cases.
Original comment by nev...@gmail.com
on 10 Jun 2013 at 9:53
I can find you a language that does this - YAML :)
In any case, you could try to parse it as an integer, and if it fails, parse it
as a boolean.
Original comment by jbe...@gmail.com
on 10 Jun 2013 at 10:04
The yaml spec says nothing about converting values from one to another, it
lists out grammar and parser rules just like any other language but doesn't
touch on things only a compiler would worry about. The is a method is at that
level, no? This is where the conversion to other types would happen in the
plugin api as well, right?
It is overly restrictive to not support casts between integer/boolean when the
scalar type is the other case, and you don't break any standards by doing so.
I hope you'll consider changing it...
Original comment by nev...@gmail.com
on 10 Jun 2013 at 10:21
As far as I can tell, what you're proposing is pretty far-reaching and
difficult. You want yaml-cpp to be able to detect "conversion chains", e.g.:
node.as<X>();
should determine if there is a conversion route from the "intrinsic" type of
the node to X, and then convert it accordingly. Should floats be truncated to
int? Signed be converted to unsigned? Etc...
Are there any other YAML parsers that handle this the way you're suggesting? As
far as I can tell, all of the ones in dynamically-typed languages simply
auto-type it and then rely on language features to cast to your heart's
content. In C++, I can't rely on auto-typing :)
Original comment by jbe...@gmail.com
on 10 Jun 2013 at 10:28
Yes most implementations rely on duck-typing but you obviously don't have the
luxury of duck-typing built in to c++... but this is some of what Node
addresses. Yes I don't know where the line should be drawn for floats
truncated to int but again the boolean/int stuff is ubiquitous. snakeyaml also
uses first class numeric types which all have conversion methods defined so in
some senses yaml-cpp falls into a class of it's own, distinct from the spartan
libyaml (which itself was developed for use with python). All implementations
except for libyaml would support a one liner that handles my use case fairly
cleanly and involve a cast operation/method... but with what you propose I
should query the type or catch exceptions and retry, both are longer and
unsavory.
Because node is your "any" type container, it's where the operations have to be
defined if convenience as approachable as that of other implementations, even
if some of the fault of that lies with language design choices.
Original comment by nev...@gmail.com
on 10 Jun 2013 at 10:53
Do you have a link to snakeyaml's implementation of this behavior?
Original comment by jbe...@gmail.com
on 10 Jun 2013 at 11:22
You may have miss-understood, snakeyaml uses first class numeric types, like
Integer as opposed to int, all of these have methods for converting from one
type to another at run time (e.g. "explicit" duck-typing?).
http://docs.oracle.com/javase/6/docs/api/java/lang/Number.html
You may point out that Boolean doesn't implement Number, this is because java
at it's lowest levels doesn't consider boolean types as an integral type and so
no conversions are allowed on that specific type, so you must use if/switch
statements to work with it (this is not true of other types though). In c++
bool is an integral type, however:
http://en.cppreference.com/w/cpp/types/is_integral
Original comment by nev...@gmail.com
on 10 Jun 2013 at 11:53
Hmm; it sounds like you're saying that snakeyaml is another implementation that
doesn't make this a one-liner. Is that correct? Do you know of any
implementation in a statically-typed language that makes this a one-liner?
Original comment by jbe...@gmail.com
on 11 Jun 2013 at 9:28
Yes you are right that it doesn't make it because the language itself doesn't
consider bools as an integral type at all (a controversial and unsettled
philosophy) and most implementations of yaml are with languages are more
duck-typing (ruby (pure? syck?), python (libyaml), matlab (snakeyaml)). If you
want to take the example of float/long/short casting, it is a one liner with
snakeyaml but boolean is an edge case in java. So I'm wrong on statically
typed languages supporting a one liner boolean casting to int by this caveat.
C# has the same philosophy on bools as not an integral type as well but allows
runtime conversion from static types, including strings, as well as Objects to
ints through the System.Convert class, which allows for a one liner. The .net
offerings for yaml are less mature however, but do not depend on syck or
libyaml. yamldotnet leaves YAML scalars as strings for the user to work with
where as yaml .net parser (a student project) relies completely on runtime
querying of type and casting to the appropriate Node specialization class
before accessing the contents. As far as I can tell there these are noticeably
less rich implementations than yaml-cpp.
haskell's implementations are pretty much just parsers, one the reference
parser, another is an event based implementation (like sax), and the last I
found is a syck based implementation which again leaves scalars as strings as
far as I can tell. ocaml's implmementation also uses syck.
So I can't show you a statically typed implementation in a static language that
does allow a one linear but I hope you see it's just because of some details
and immature implementations. Had snakeyaml been in c# it'd be there, and java
derivative languages follow suite with the boolean is not integral philosophy.
Coming back from that though you have Node behaving as a container taking care
of all casting/converting... but through this exercise I fully realize you
completely rely on the user and the conversion api to really get at scalar
types, which are internally just strings. You do not do keep type info on hand
for what a scalar actually parses to (can be done with or without RTTI just the
same as you've done with map, seq, scalar, null). Actually this would probably
speed you up since you wouldn't be allocating so many stringstreams... but more
on topic I can understand better why would refrain from the support as you must
put a boolean parser with an int parser which definitely looks ugly. Still, at
the high level it's nonsensical behavior.
At this point I give in, I feel I make a good point but it would involve large
or ugly changes to yaml-cpp to do well.
Original comment by nev...@gmail.com
on 11 Jun 2013 at 11:50
Original issue reported on code.google.com by
nev...@gmail.com
on 10 Jun 2013 at 8:18