toml4j icon indicating copy to clipboard operation
toml4j copied to clipboard

Deep merge

Open gustavkarlsson opened this issue 8 years ago • 6 comments

Any plans or thoughts on implementing a deep merge option for the different read methods?

Let's say you have:

logging = "INFO"
[server]
port = 1234

and then read:

logging = "DEBUG"
[server]
host = "myservice.com"

it would produce

logging = "DEBUG"
[server]
port = 1234
host = "myservice.com"

instead of the full server table being overwritten.

gustavkarlsson avatar Jul 12 '16 13:07 gustavkarlsson

I'm very wary of this, because there are so many possible corner cases and lots of things to explain to users. What about arrays and table arrays? Or removing a key?

I feel like the library should offer a simple solution and let applications do more sophisticated things.

If I'm not mistaken, even Jquery has avoided deep merging (avoided it for a long time). If you can find another library with a well-tested deep merge algorithm, I'll take a look at it.

mwanji avatar Jul 12 '16 16:07 mwanji

I understand that it's not trivial. And yeah, it could cause confusion if not done carefully. If I were to attempt this, would you at least be interested in looking at a pull request (well tested, of course) or would I be wasting my time?

gustavkarlsson avatar Jul 13 '16 19:07 gustavkarlsson

The first step would be to outline documentation of the API and user-facing explanatory examples. I think that's more important and less time-consuming than an implementation, right now.

mwanji avatar Jul 13 '16 20:07 mwanji

+1 I need this feature too. I think the expected result of a merge is very straight forward:

  • keys in both configs are overriden by the later
  • tables are combined
    • result table contains all keys from both tables
    • duplicated keys will be overriden by the later
  • arrays are merged (elements from the second come last)

This way you can override arrays and tables if you merge an empty value before:

Toml toml = new Toml().read("a=[1,2,3]");
toml.read("a="); // a is now empty
toml.read("a=[4,5,6]"); // a now contains 4, 5, 6

radicarl avatar Mar 20 '17 12:03 radicarl

@radicarl Would the default values feature fulfill your needs? I think it could get you started.

However, I'm not sure I agree with tables being merged. What if you want to replace a table rather than combine the values?

Do you have examples of how other libraries handle merging?

mwanji avatar Mar 20 '17 16:03 mwanji

No, default values will not help, because I have deep tables. Also the entrySet-Method returns only the entries from the second toml file and none of the default values. Is this a bug?

Overriding tables should work like overriding arrays. But maybe toml is not meant for this. The documentation forbids duplicated keys. I think I have to choose a different language.

HOCON allows merging of tables/objects: https://github.com/typesafehub/config/blob/master/HOCON.md#array-and-object-concatenation

radicarl avatar Mar 21 '17 08:03 radicarl