Wednesday, October 24, 2012

Back to Dart: New Optional Constructor Syntax

‹prev | My Chain | next›

I am more or less done researching for Gaming JavaScript. To be sure, there will be more that I have to dig into at various points as I touch up chapters, but at this point it is mostly brain dump. So I am shifting to catch up on other projects.

I am hard pressed to decide what is in more desperate need of an update at this point, SPDY Book or Dart for Hipsters. I do have a better handle on the latest changes to SPDY, having done much research and development when version 3 of the protocol came out. In the meantime, it seems that Dart has been changing rapidly, so I will focus there for the foreseeable future.

There are a ton of new changes in the m1 release of the language. Rather than working through those changes one-by-one, I will instead start by trying to get my dart comics sample app, along with the Hipster MVC library on which it is built, to work with recent dart builds. This should be fun.

I grab the latest Dartium, fire up the node.js backend and access the site. Not surprisingly, it does not work. In the Dart console, I find:
Exception: No such method: 'Comics', url 'http://localhost:3000/scripts/main.dart' line 14 pos 37
    , comics_view = new Views.Comics(

Stack Trace: #0      NoSuchMethodErrorImplementation._throwNew (dart:core-patch:401:3)
#1      main (http://localhost:3000/scripts/main.dart:14:37)
Interestingly, line 14 is a constructor for the Comics.View:
#import('Collections.Comics.dart', prefix: 'Collections');
#import('Views.Comics.dart', prefix: 'Views');
// ...

main() {
  var my_comics_collection = new Collections.Comics()
    , comics_view = new Views.Comics(
        el:'#comics-list',
        collection: my_comics_collection
      );

  my_comics_collection.fetch();
  // ...
}
What is interesting about this is that the Collections.Comics class seems to be defined, while Views.Comics is not. Both are imported in the same manner—prefix and all—so the problem is presumably in the library code.

And indeed, I run afoul of my first M1 breaking change: optional parameters are specified differently. Optional parameters are a fantastic little feature of Dart that formalizes what many other languages force programmers to do manually—handle default and optional parameters.

Currently, the Comics class uses the old square brackets to indicate optional parameters:
class Comics extends HipsterView {
  Comics([collection, el]):
    super(collection:collection, el:el);
  // ...
}
In M1, square brackets are used to capture optional, positional parameters. In the above, I am saying that the first and second parameters are optional and should not be named. Optional named parameters, which I want here, are defined inside a more hash-like curly braces:
class Comics extends HipsterView {
  Comics({collection, el}):
    super(collection:collection, el:el);
  //...
}
It makes all kinds of sense to use curly braces to indicate named parameters like: new Views.Comics(el: '#comics-list', collection: my_comics_collection) because this is much more akin to the options-object that we are forced to use in languages like JavaScript.

What is really nice about Dart constructor parameters is the ability to assign instance variables directly from the constructor definition. The Comics view constructor redirects to the superclass (HipsterView) constructor with two optional, named parameters. In the superclass, those named parameters correspond to instance variables of the same name. In most languages, I would need to then jump through the assign-instance-variable-if-supplied-in-the-constructor hoops.

In Dart, I can simply declare them in the constructor with the this keyword:
class HipsterView {
  HipsterCollection collection;
  HipsterModel model;
  Element el;

  HipsterView({el, this.model, this.collection}) {
    // ...
  }
}
If the model or collection named parameters are supplied, then the instance variable of the same name is assigned. That's just freaking awesome.

I am not even close to fixing all of the problems in dart-comics and HipsterMVC, but I still call it night here. I may be done with research on Gaming JavaScript, but I still have a ton of writing to do.


Day #549

No comments:

Post a Comment