jbeder / yaml-cpp

A YAML parser and emitter in C++
MIT License
4.91k stars 1.77k forks source link

Empty strings are silently replaced with 'null' now #1290

Open Anton3 opened 6 days ago

Anton3 commented 6 days ago

I've been upgrading from an older yaml-cpp version to 0.8.0. What I found different is that for empty strings, behavior has changed, they are now replaced with "null".

For example, given the following YAML:

message:
node["message"].as<std::string>()  //=> "null"

I know that such a value can be interpreted as null, hence IsNull() -> true is expected.

However, my parsing for this particular option does not allow for nulls, I always interpret this as a string. In my case message="" vs message="null" makes a difference, and I can't easily distinguish between them.

Can yaml-cpp revert to the old behavior in this case? For an empty value, I want Scalar() == as<std::string>() == "" For null value, I want Scalar() == as<std::string>() == "null"

Anton3 commented 6 days ago

This might be okay if the new behavior is more consistent. Null-like strings should be escaped as '' and 'null' anyway. Just notice that some breaking changes have happened around handling nulls.

jbeder commented 6 days ago

You can check the type of the node. Is that sufficient?

Anton3 commented 6 days ago

Not really, because earlier I force-interpreted the node as a string. I guess that's not possible in the recent versions of the library.

The way forward for me will be to go through my configs, replacing <empty> with '' and null with 'null'.

Anton3 commented 5 days ago

Reopening because of inconsistency.

According to #590, it seems that a user may want to get the value of a Scalar (in the meaning from the spec), ignoring nulls, and that the library supports it.

But what happens in practice is, if the Scalar is a null, then yaml-cpp replaces its value (which can be <empty> | null | Null | NULL | ~) with "null", without any way to get the original value.

What should happen is, the original text representation of the null value should be kept in the Scalar() field. Then as<std::string>() should retrieve this stored Scalar() field.

jbeder commented 5 days ago

Yeah that's reasonable.