Fake for-loops and comprehensions
At the beginning of your post, you say that you can't always achieve everything with looping in one line in CoffeeScript. When you say that, I assume you are taking about the each_file
:
each_file: (index = 0) ->
length = @files.length
file = @files[index]
if index < length
Types.read file, @next.bind @
@each_file index + 1
This is kinda ugly right now because you seem to be using a method to fake a for-loop. Luckily, with CoffeeScript's comprehensions, we can turn this into a simple 1-line expression.
First, we need to be iterating through all of the @files
. That can be written simply like this:
Types.read(file, @next.bind this) for file in @files
This is a comprehension that will go through all of the @files
and substitute the file
in the Types.read
call with the current file it's looping over.
Now that we have this, you can remove that
file = @files[index]
line, along with that single index
parameter. Why? Because, now that we have this loop, we no longer have any of that method-recursion-fake-for-loop-idness.
Along with those, since this is now a comprehensions that loops through all the values in an array, we don't need to do any checking to make sure the index is less than the length.
if index < length
Can be removed. Guess what your method looks like now?
each_file: () ->
Types.read(file, @next.bind @) for file in @files
The above method will do exactly what it was doing before: it will go through all of the files in @files
and pass it into Types.read
along with @next.bind @
.
What's different now?
It's much shorter and much simpler than what you were doing before. As I already stated, you seemed to be reinventing the for
loop with that recursion you were doing.
It's more idiomatic. CoffeeScript has those comprehensions so you can simplify long tasks into a few small and readable lines.
Misc.
init: (files, cb) ->
@files = files
@cb = cb
This can be shortened to this:
init: (@files, @cb) ->
The CoffeeScript compiler treats parameters with a @
before them as a name of a property to set to the parameter. For example, @files
will become:
this.files = files
in the method body.
Types.read
doing? \$\endgroup\$