I prettied up the Dart web server code in my Dart Comics sample app quite a bit recently. As pretty as it is, I have been lamenting the lack of a splat operator or an
apply
method for functions to make things even prettier. It turns out that there is, in fact, a Function.apply, so let's see if that will help.The first thing that I notice is that it is a static method, so something like this is probably not going to work:
import 'dart:io'; main() { HttpServer app = new HttpServer(); app.addRequestHandler.apply([Public.matcher, Public.handler]); // ... app.listen('127.0.0.1', 8000); }And indeed that does fail when I try to start up my server:
➜ dart-comics git:(app.dart) ✗ dart app.dart Unhandled exception: NoSuchMethodError : method not found: 'apply' Receiver: Closure: (dynamic, (dynamic, HttpRequest) => bool, (dynamic, HttpRequest, HttpResponse) => void) => dynamic from Function 'addRequestHandler':. Arguments: [GrowableObjectArray] #0 Object._noSuchMethod (dart:core-patch:1260:3) #1 Object.noSuchMethod (dart:core-patch:1263:25) #2 main (file:///home/chris/repos/dart-comics/app.dart:9:30)I am unsure if the static version of
Function.apply
will retain the object context (e.g. this
), but there is one way to find out. So I convert that broken apply()
to a full Function.apply()
:main() { HttpServer app = new HttpServer(); Function.apply(app.addRequestHandler, [Public.matcher, Public.handler]); // ... app.listen('127.0.0.1', 8000); }But, when I try again, I get:
➜ dart-comics git:(app.dart) ✗ dart app.dart Unhandled exception: UnimplementedError: Function.apply not implemented #0 Function.apply (dart:core-patch:721:5) #1 main (file:///home/chris/repos/dart-comics/app.dart:9:17)Dang it! It's still just a tease. Oh well, at least it is on the radar.
So I switch to fixing a small bug in my sample app. OK, maybe not that small. It turns out that my scheme to grab the next available ID does not work:
class Comics { static Dirty db = new Dirty('dart_comics.db'); // ... static post(req, res) { var input = new StringInputStream(req.inputStream); // ... input.onClosed = () { var graphic_novel = JSON.parse(post_data); graphic_novel['id'] = db.length + 1; }; } }The problem here is that if I delete the first record in the database then
db.length + 1
now refers to the last record in the DB, not the next available ID. The way that I got around this in the node.js version of the application was to make use of node-dirty-uuid. In Dart, I am going to give dart-uuid a try. Since this is Dart and since dart-uuid is available in Dart Pub, trying this out is a simple matter of adding dart-uuid to my application's
pubspec
dependencies:name: Dart Comics dependencies: dirty: any uuid: anyAfter a simple
pub install
, I am ready to go.And it turns out to be as simple as importing dart-uuid, instantiating a UUID object, and using it:
import 'package:uuid/uuid.dart'; class Comics { static Uuid uuid = new Uuid(); static Dirty db = new Dirty('dart_comics.db'); // ... static post(req, res) { var input = new StringInputStream(req.inputStream); // ... input.onClosed = () { var graphic_novel = JSON.parse(post_data); graphic_novel['id'] = uuid.v1(); }; } }With that, my problem is solved.
Day #582
No comments:
Post a Comment