This is what we currently have to do in D:
auto app = new Application();
auto win = new Window();
with (win) {
setTitle("Example");
setDefaultSize(200, 200);
setChild(mainBox);
}
app.addWindow(win);
In most cases you really do not want the auto win = new Window;
line because you should be able to do it all inside the with block. Since with statement does not allow initialisation one would try:
auto app = new Application();
with (new Window) {
setTitle("Example");
setDefaultSize(200, 200);
setChild(mainBox);
app.addWindow(???); // we CAN'T refer to the object created by the `new Window`
}
What I do is I make classes that I want to use the with statement on have a property called self
that simply return this. This allows me to write something like:
auto app = new Application();
with (new MyWindow) {
setTitle("Example");
setDefaultSize(200, 200);
setChild(mainBox);
app.addWindow(self); // MyWindow implements self
}
I would still prefer an initialisation because it matches what we have in the for
statement, but I would not mind if D allows something like this
in the with block, yet I would not call it this
. self
maybe. that
? I do not know. This is precisely why I prefer the initialisation instead - because I do not know what would be the best name for this reference...
Please do not even start with the fluent APIs in this thread. Why? Because what I am asking above does not require people to refactor their libraries to make them "fluent", it will work out of box with anything.
For those who wonder what am I talking about - let's assume this particular library I am using has a fluent API. Then I could write the code above like this:
auto win = new Window;
win.setTitle("Example")
.setDefaultSize(200.200)
.setChild(mainBox);
app.addWindow(win);
This would work because all Window methods return this. We do not always have luxury of being able to change the library we use, especially make such a drastic change so that all methods return this (which would be required for the fluent API to work).