I have myself a nice, Dart modal dialog. It is an adapter for Element with the following constructors:
class ModalDialog implements Element {
Element el, bg;
factory ModalDialog() => new ModalDialog.tag('div');
ModalDialog.tag(String tag) {
el = new Element.tag(tag);
}
ModalDialog.html(String html) {
el = new Element.tag('div');
el.innerHTML = html;
}
// ...
}The factory constructor allows me to instantiate a modal dialog thusly:el = new ModalDialog(); el.innerHTML = '<form>...</form>';That works, but the factory constructor is more ceremony than Dart requires. In fact, I can use a redirecting constructor, as Kasper Lund pointed out. Thus I can still instantiate simple modal dialogs the same way if I change the constructor to:
class ModalDialog implements Element {
Element el, bg;
ModalDialog(): this.tag('div');
// ...
}That is some compact syntax—the vanilla ModalDialog() constructor redirects to the ModalDialog.tag() constructor with an argument of 'div'. I really like that.Something else that Kasper mentioned was that redirection also works in constant constructors. Upon hearing that, I could only wonder what the heck is a constant constructor? To answer that, I return to my
Player class:class Player {
int x, y;
Player.xy(this.x, this.y) {
if (x == null) x = 0;
if (y == null) y = 0;
}
}I can instantiate a player as new Player.xy(25, 25); and the player is positioned at x=25 and y=25. The thing about most Dart classes is that you cannot simply assign them outside of functions:// this won't work...
var me = new Player.xy(25, 25);
main() {
// do stuff here ...
}The problem is that new Player.xy(25, 25) is not a compile time constant. I can declare the me variable in a Dart libraries scope, but I cannot assign it—unless the assignment is a constant expression. Actual assignment is deferred until runtime (e.g. inside the main() function).To convert
Player into a compile time constant, I need to make all instance variables final:class Player {
final int x, y;
// ...
}Admittedly, there is not much sense to a game in which all player positions are final, but why let that get in the way of a good topic exploration?In addition to final instance variables, I also need a constant constructor. Here, I use a redirecting, constant constructor to point the vanilla
Player() to the Player.xy() version:class Player {
final int x, y;
const Player(): this.xy(0,0);
Player.xy([this.x, this.y]) {
if (x == null) x = 0;
if (y == null) y = 0;
}
}With that, I can now instantiate a constant object at compile time:final me = const Player();
main() {
// Not much to do here since players don't move
}Clearly I need a better use-case for constant objects that an immovable Player if I am to include a treatment of this topic in Dart for Hipsters. And I do need to include it—these redirecting constructors are quite nice.Day #330
No comments:
Post a Comment