Mike Ellis Mike Ellis - 1 month ago 6x
CoffeeScript Question

CoffeeScript: Spurious comma in comprehension joined by empty separator

I wanted a convenience function to catenate jQuery parent > child selector strings. I can't get the following to work in CS 1.10.0 (also tested in 1.7.1). What am I doing wrong?

pcsel = (parent_sel, child_sels...) ->
### Uitlity for forming parent > child selector string ###
childchain = [" > " + child for child in child_sels]
parent_sel + childchain.join('')

console.log pcsel("foo", "bar") # OK. yields "foo > bar"
console.log pcsel("foo", "bar", "glop") # BAD. yields "foo > bar, > glop"
# Sanity check
console.log "foo" + [" > bat", " > glop"].join('') # OK. yields "foo > bar > glop"


(I've also posted this as an issue in the CS repository)


A loop comprehension:

expr for e in array

evaluates to an array. That means that this:

[ expr for e in array ]

is actually a single element array whose first (and only) element is the array from the loop. More explicitly:

i for i in [1,2,3]

is [1,2,3] but this:

[ i for i in [1,2,3] ]

is [[1,2,3]].

Your problem is that childchain in pcsel ends up with an extra level of nesting and the stringification from the join call adds unexpected commas.

The solution is to fix pcsel:

childchain = (" > " + child for child in child_sels)
# -----------^-------------------------------------^

You need the parentheses (not brackets) to get around precedence issues; parentheses (()) and brackets ([]) serve entirely different functions so you need to use the right ones.