jmonkeyengine icon indicating copy to clipboard operation
jmonkeyengine copied to clipboard

Make AppSettings#put() return this

Open MeFisto94 opened this issue 6 years ago • 6 comments

Breaking-Change but I think it'll help writing more compact code in some scenarios while the trade off is just having to clean rebuild code after the upgrade (the new jme version would be binary incompatible to everything using app settings, so mostly applications, not libraries).

What do you think of that?

MeFisto94 avatar Jan 12 '20 14:01 MeFisto94

put() should return the previous value. If it doesn't then it's misnamed. I thought AppSettings implemented the Map interface which is where it got put... but either way, Java developers are going to expect put() to return the previous value.

If you want a method to chain calls together then make a different one, I guess.

pspeed42 avatar Jan 12 '20 15:01 pspeed42

Currently they (the specifc ones like putString) all return void, even though AppSettings extend HashMap, so it's probably only a matter of a return statement.

Any suggestions on how the different method would be called? set? add isn't quite right, I think.

MeFisto94 avatar Jan 12 '20 15:01 MeFisto94

.builderPut()? .chainPut()? Just throwing out some ideas

grizeldi avatar Jan 14 '20 12:01 grizeldi

I'm fine with "set" personally.

Looking at the code, it's as I suspected that AppSettings extends HashMap... which is why put() will return the previous value and that's what everyone will expect.

So if you want to have: settings.foo("bar", 1).foo("bax", 2); instead of: settings.foo("bar", 1); settings.foo("bax", 2);

...then I suggest using "set". Though to be honest, the use-cases for this seem rare to me.

pspeed42 avatar Jan 14 '20 15:01 pspeed42

Why not create a Builder?

One of those ways would work, I would say (3) is the most elegant:

settings = AppSettingsBuilder.of(settings).with("foo", 2).with("bar",3).build();    //(1)
AppSettingsBuilder.empty().with("foo", 2).with("bar",3).applyTo(settings); // (2)
settings.builder().with("foo", 2).with("bar",3).apply();    // (3)

You could make the builder use a fluid (chainable) interface without changing the original class at all, or just by adding one method, which should be binary-compatible.

NetzwergX avatar Jan 20 '20 15:01 NetzwergX

But it's one new class that requires support to turn one place in the application from four lines of code to one line of code. A place most applications set once and never touch.

We've now spent more time discussing this than it would save all of the developer time in the world. :)

pspeed42 avatar Jan 20 '20 16:01 pspeed42