satyr / coco

Unfancy CoffeeScript
http://satyr.github.com/coco/
MIT License
498 stars 48 forks source link

ability to use instance variable as index in for loop #152

Closed andrewrk closed 12 years ago

andrewrk commented 12 years ago

code:

callback() for callback, @i of callback_list

expected:

var this.i, callback, __ref, __len;
for (this.i = 0, __len = (__ref = callback_list).length; this.i < __len; ++this.i) {
  callback = __ref[this.i];
  callback();
}

actual:

Error: Parse error on line 1: Unexpected 'OF'

alternately, is there a better way to factor this class?

class EventEmitter
  ->
    @event_handlers = {}

  on: !(event_name, handler) ->
    @handlers(event_name).push handler

  removeEventListeners: !(event_name) ->
    @handlers(event_name).length = 0

  removeListener: !(event_name, handler) ->
    handlers = @handlers(event_name)
    for h, i of handlers
      if h is handler
        handlers.splice i, 1
        if @i? and @i >= i
          @i -= 1
        return

  # protected
  emit: !(event_name, ...args) ->
    # loop with @i so we can adjust if the user deletes
    # during the callback
    handler(...args) for handler, @i of handlers_list

  # private
  handlers: (event_name) -> @event_handlers[event_name] ?= []
satyr commented 12 years ago

The index is intentionally variable-only as using property for it is an anti-pattern performance-wise.

is there a better way to factor this class?

 emit: !(event_name, ...args) ->
   # loop with @i so we can adjust if the user deletes
   # during the callback
   handler(...args) for handler, @i of handlers_list

I'd avoid iterating a dynamically changing list:

emit: !(event_name, ...args) ->
  for h of @event_handlers@@[event_name]concat!
    h.apply null, args
andrewrk commented 12 years ago

I think that is the cleanest way to factor the code. I originally copied the array before looping over it, but then wanted to avoid an array copy since emit is used in a game loop, which should be fast.

Anyway I think you're right that coco should not make it easy to iterate using an assignable other than a variable for the index.