Динамические методы CoffeeScript - PullRequest
6 голосов
/ 28 июня 2011

Я пытаюсь динамически создавать методы в сценарии кофе, но, как показывает мой код, итератор, который я использую для создания методов, не сбрасывает свои переменные между итерациями, поэтому я получаю общие переменные, которые конфликтуют:

class MyClass
  constructor: (@name) ->

  for k, v of ['get', 'set']
    console.log('creating method: ' + v)
    MyClass::[v] = (args...) ->
      method = v
      console.log('executing method: ' + method)

o = new MyClass('dummy')
o.get()
o.set()

Выходы:

> creating method: get
> creating method: set
> executing method: set
> executing method: set

кто-то знает, что я делаю не так?

Ответы [ 2 ]

7 голосов
/ 28 июня 2011

мю правильно диагностировал проблему. Наиболее прямым решением является использование ключевого слова do языка CoffeeScript, которое создает и запускает внутреннюю функцию, которая фиксирует значения переменных, которые вы передаете:

for k, v of ['get', 'set']
  do (k, v) ->
    console.log('creating method: ' + v)
    MyClass::[v] = (args...) ->
      method = v
      console.log('executing method: ' + method)

Я говорю об этой функции в моей статье PragPub, A CoffeeScript Intervention .

5 голосов
/ 28 июня 2011

Ваша внутренняя функция:

(args...) ->
  method = v
  console.log('executing method: ' + method)

на самом деле является замыканием v, поэтому при его выполнении v будет вычислять его последнее значение в цикле (т.е. set). Похоже, вам просто нужно немного перебить закрытие:

build_method = (v) ->
  (args...) ->
    method = v
    console.log('executing method: ' + method)

А потом:

for k, v of ['get', 'set']
  console.log('creating method: ' + v)
  MyClass::[v] = build_method(v)

Имейте в виду, что CoffeeScript - это просто JavaScript с разной структурой, поэтому он страдает от множества одинаковых проблем (как и любой язык с замыканиями), и эти проблемы имеют одинаковые решения.

...