Strange behavior with list comprehension (Example included)


#1

I could possibly be missing something, but let me explain what’s happening.

I have a set of Markers (highlight regions) that are being set on keypress. I’m trying to detect if the cursor is at the beginning of the highlight region, and return it only if it is.

So, I have this code snippet:

        position = cursor.getBufferPosition()
        marks = @findMarks(containsBufferPosition: [position.row, position.column])
        mark =  mark for mark in marks when mark.getStartBufferPosition().isEqual(position)

        console.log mark for mark in marks when mark.getStartBufferPosition().isEqual(position)
        console.log mark

The console won’t log a Marker if my cursor is at the end of a Marker region, but it will still return a mark into the mark variable. Am I missing something here with list comprehensions and what should be returned? I’m expecting undefined, but I get the Marker!


#2

The issue here is that you use the same variable name mark for the inner and outer loop variable. It means that mark is declared before the loop, and is used in the loop to store the current array element so it will never be null or undefined after the loop even when there’s no marker that pass the when test in your loop as it will always holds the last iteration value.

See the output here.

You should write something like that instead:

position = cursor.getBufferPosition()
marks = @findMarks(containsBufferPosition: [position.row, position.column])
marker = mark for mark in marks when mark.getStartBufferPosition().isEqual(position)

console.log mark for mark in marks when mark.getStartBufferPosition().isEqual(position)
console.log marker

#3

I didn’t even think about looking at the generated JS. This is really the first bit of coffescript I’ve written. Thank you so much! I fixed it last night, but I wasn’t sure what exactly was wrong. This was a perfect explanation. I had assumed that the mark variable in the for-comprehension was in a different scope. I guess that shows what you get for assuming.

P.S. How did you get your code to be nicely formatted like that? I tried the 4 spaces, but it resulted in the ugly mess you see above.


#4

I used the triple backticks code block from Github Flavored Markdown (supported by Discourse :))