Working with some of the dart:io SDK can be quite tedious and hard to navigate.
Trying to do simple things like finding the absolute path of the current directory is painful.
Browsing around and looking at what's available statically I tried stuff like this:
print(new Directory('.').current.path);
print(new Directory('').current.path);
print(new Path('.').directoryPath);
print(new Path('.').directoryPath.toNativePath());
print(new File('.').path);
Whilst all these yield '.', basically I couldn't find any way to retrieve the absolute path of the current directory.
In node.js it's available with the module variable '__dirname'. It might be a magic variable but at least it's discoverable and works well with all their path libs since they all work with strings.
So in the end I'm having to do what looks like a blocking IO call just to get it:
String __dirname = new File('.').fullPathSync(); //is there anything better?
The Path class is also cumbersome to work with, it mixes Path and String which IMO creates un-necessary friction given that File and Directory only works with strings.
In end as I wasn't getting much value from it as all the code ended up being more verbose so I just ended up porting the behavior of node.js path APIs internally, since they're simpler and easier to work with: http://nodejs.org/api/path.html
And it also looks like the HTTP Server APIs got a change for the worse, this is now the example given to set a Content-Type:
http://api.dartlang.org/docs/releases/latest/dart_io/HttpResponse.html
HttpResponse response = ...
response.headers.contentType
= new ContentType("application", "json", charset: "utf-8");
It's so long that the example code to set a singe field wraps on 2 lines. I don't see how it can be more readable given that Content-Types are always read in their concatenated form (i.e. application/json) in every other place I've seen them. I'm also assuming that this will always be slower than setting a literal string so I feel like I'm paying a perf penalty for the price of having more verbose and less readable code.
There are many places where the SDK APIs seem clean and really well thought out, but I also think there's a risk of introducing too many types (esp around strings) which seems to just cause friction, promoting less readable and more verbose code. IMO APIs should be weighed against node.js's APIs and measured on their readability and imposed friction.
- Demis
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
Trying to do simple things like finding the absolute path of the current directory is painful.
Browsing around and looking at what's available statically I tried stuff like this:print(new Directory('.').current.path);
print(new Directory('').current.path);Both of these throw:Breaking on exception: Class '_Directory' has no instance getter 'current'.
print(new Path('.').directoryPath);
print(new Path('.').directoryPath.toNativePath());
print(new File('.').path);Whilst all these yield '.', basically I couldn't find any way to retrieve the absolute path of the current directory.
In node.js it's available with the module variable '__dirname'. It might be a magic variable but at least it's discoverable and works well with all their path libs since they all work with strings.
The Path class is also cumbersome to work with, it mixes Path and String which IMO creates un-necessary friction given that File and Directory only works with strings.
In end as I wasn't getting much value from it as all the code ended up being more verbose so I just ended up porting the behavior of node.js path APIs internally, since they're simpler and easier to work with: http://nodejs.org/api/path.html
And it also looks like the HTTP Server APIs got a change for the worse, this is now the example given to set a Content-Type:
http://api.dartlang.org/docs/releases/latest/dart_io/HttpResponse.htmlHttpResponse response = ...
response.headers.contentType
= new ContentType("application", "json", charset: "utf-8");It's so long that the example code to set a singe field wraps on 2 lines. I don't see how it can be more readable given that Content-Types are always read in their concatenated form (i.e. application/json) in every other place I've seen them. I'm also assuming that this will always be slower than setting a literal string so I feel like I'm paying a perf penalty for the price of having more verbose and less readable code.
There are many places where the SDK APIs seem clean and really well thought out, but I also think there's a risk of introducing too many types (esp around strings) which seems to just cause friction, promoting less readable and more verbose code. IMO APIs should be weighed against node.js's APIs and measured on their readability and imposed friction.
response.headers.contentType = ContentType.parse("application/json; charset=utf-8");
response.headers.contentType = "application/json; charset=utf-8";
response.headers.contentType = ContentTypes.HTML_TYPE;
response.headers.contentType = ContentTypes.HTML;
--
Working with some of the dart:io SDK can be quite tedious and hard to navigate.
The Path class is also cumbersome to work with, it mixes Path and String which IMO creates un-necessary friction given that File and Directory only works with strings.
In end as I wasn't getting much value from it as all the code ended up being more verbose so I just ended up porting the behavior of node.js path APIs internally, since they're simpler and easier to work with: http://nodejs.org/api/path.html
I don't see why we need the Path class anymore, this should be baked is the default since it promotes much less friction when dealing with Files/Directories/paths.
Hi Anders,Thanks for your comments.Yeah Directory.current is definitely better than __dirname, and would've saved me a lot of time if I got to it the first time.This should no longer be an issue once static methods are taken out of instance intelli-sense and a checked error/warning is raised when trying to access a static member in an instance context.I understand there are times when OOP APIs can be preferable, but it should be weighed against each use-case.Nice thing about HTTP as a text protocol is that setting any HTTP Headers are consistent and flexible, thanks to which also allows us to have a minimal and flexible API Surface (which based on some of the other APIs, looks to be a goal for Dart).When you start typing them it just adds friction, and I'm not sure when benefit this provides? Even as a web framework author, I rarely ever deal with structured Content-Type segments.Given that in the end a string has to be emitted on the wire, the API must be for developer convenience and I don't see even how the the condensed example:response.headers.contentType = ContentType.parse("application/json; charset=utf-8");Is any better than using a string?response.headers.contentType = "application/json; charset=utf-8";So we've now go from an unstructured string into a typed model, that in the end gets converted back into a raw string again before getting emitted on the wire.
Which requires less boilerplate/friction under the hood. I'd expect most of the times given that setting the Content-Type is a common operation that not many people will use theIMO the Dart IO HTTP APIs should be approached in the same way as node.js, i.e. a minimal, flexible and un-opinionated foundation upon which higher-level web frameworks can be built-on.If others see value in typing the whole world with every known HTTP Status code or HTTP Headers, then that's an opinion that can be isolated to these typed/high-level frameworks.But imposing them on the lowest level API (i.e. the Dart SDK) creates friction on those frameworks that don't want this.Some things I look to when designing API's is a trade-off between capturing "user intent" in its most readable form and balancing that with maintaining a lean code-base with a flexible and reduced API surface.This seems to contradict both of these goals since unnecessary types create friction which prevents us from being able to use generic string containers to hold and carry information, i.e. being able to pass and set all headers generically with just a Map<String,String>.
On Monday, July 1, 2013 12:05:29 PM UTC-7, mythz wrote:Hi Anders,Thanks for your comments.Yeah Directory.current is definitely better than __dirname, and would've saved me a lot of time if I got to it the first time.This should no longer be an issue once static methods are taken out of instance intelli-sense and a checked error/warning is raised when trying to access a static member in an instance context.I understand there are times when OOP APIs can be preferable, but it should be weighed against each use-case.Nice thing about HTTP as a text protocol is that setting any HTTP Headers are consistent and flexible, thanks to which also allows us to have a minimal and flexible API Surface (which based on some of the other APIs, looks to be a goal for Dart).When you start typing them it just adds friction, and I'm not sure when benefit this provides? Even as a web framework author, I rarely ever deal with structured Content-Type segments.Given that in the end a string has to be emitted on the wire, the API must be for developer convenience and I don't see even how the the condensed example:response.headers.contentType = ContentType.parse("application/json; charset=utf-8");Is any better than using a string?response.headers.contentType = "application/json; charset=utf-8";So we've now go from an unstructured string into a typed model, that in the end gets converted back into a raw string again before getting emitted on the wire.It seems clear that using the string is both more readable and shorter to type. On the other hand, Anders has a point that there are benefits to having ContentType.charSet, etc.However, it seems like we can easily have the best of both worlds here. Why not allow the contentType setter to accept either a String or a ContentType as the argument... if it's a String, then run it through ContentType.parse() and store it internally as a ContentType.
Which requires less boilerplate/friction under the hood. I'd expect most of the times given that setting the Content-Type is a common operation that not many people will use theIMO the Dart IO HTTP APIs should be approached in the same way as node.js, i.e. a minimal, flexible and un-opinionated foundation upon which higher-level web frameworks can be built-on.If others see value in typing the whole world with every known HTTP Status code or HTTP Headers, then that's an opinion that can be isolated to these typed/high-level frameworks.But imposing them on the lowest level API (i.e. the Dart SDK) creates friction on those frameworks that don't want this.Some things I look to when designing API's is a trade-off between capturing "user intent" in its most readable form and balancing that with maintaining a lean code-base with a flexible and reduced API surface.This seems to contradict both of these goals since unnecessary types create friction which prevents us from being able to use generic string containers to hold and carry information, i.e. being able to pass and set all headers generically with just a Map<String,String>.
Well said.Cheers,Josh
--
Support your local union types: http://dartbug.com/4938