CoffeeScript: как вернуть массив из класса? - PullRequest
4 голосов
/ 14 сентября 2011

Что не так в этом классе в CoffeeScript ??

@module "Euclidean2D", ->
  class @Point
    constructor: (x,y) -> 
      return if Float32Array? then Float32Array([ x, y ]) else Array(x,y)

Я хочу, чтобы он вел себя так:

p = new Point(1.0,2.0);
p[0] == 1.0
p[1] == 2.0

Но, тестируя с Жасмином, я получаю «Ожидаемый неопределенный равный 1».

describe "Point", ->

    beforeEach ->
      @point = new Euclidean2D.Point(1.0,2.0)

    it "extracts values", ->
      (expect @point[0]).toEqual 1.0
      (expect @point[1]).toEqual 2.0

Есть ли ошибка в CoffeeScript или в Jasmine ??

Также все это в модуле, как:

@module = (names, fn) ->
  names = names.split '.' if typeof names is 'string'
  space = @[names.shift()] ||= {}
  space.module ||= @module
  if names.length
    space.module names, fn
  else
    fn.call space

В консоли Chrome я получаю:

a = new Euclidean2D.Point(1.0,2.0)
-> Point
a[0]
undefined
b = new Float32Array([1.0,2.0])
-> Float32Array
b[0]
1

РЕДАКТИРОВАТЬ: , снова .. извините

Решил, используя комбинацию ответов @brandizzi и @ arnaud576875. @Module, представленный в официальной CoffeeScript Wiki, не работал. Результат:

class @Point
        constructor: (x, y) ->
            return if Float32Array? then Float32Array([ x, y ]) else Array(x,y)

Ответы [ 2 ]

1 голос
/ 14 сентября 2011

Вы определяете конструктор, но ожидаете, что он ведет себя как функция. Однако конструктор просто устанавливает значения в возвращаемом объекте. Поскольку ваш конструктор не устанавливает никаких атрибутов в инициализирующем объекте, это действительно бесполезно.

У вас есть несколько альтернатив:

  1. Инициализируйте класс как @amaud sugested.

  2. Возвращает значение из конструктора как @amaud sugested (что не имеет большого смысла для меня. Это не функция конструктора, как мне кажется. В этом случае решение № 3 кажется лучше).

  3. определить функцию вместо класса. ИМХО, это самое простое и функциональное решение

    @Point = (x, y) ->
        if Float32Array? then Float32Array([x,y]) else Array(x,y)
    
  4. Если вы хотите, чтобы Point была специализацией Float32Array или Array, используйте опцию # 1, но сделайте Point для наследования от класса, который вы хотите:

    superclass = if Float32Array? then Float32Array else Array  
    
    class @Point extends superclass
      constructor: (x,y) ->
        @[0] = x
        @[1] = y
    

EDIT : @ amaud676875 опубликовал интересный вопрос в качестве комментария. Поскольку разумный ответ может включать в себя некоторый код, я публикую ответ как правку.

@ amaud, для проверки вашей позиции я написал следующий модуль CoffeeScript:

class Float32Array extends Array
  first: -> # Just for testing
    @[0]


superclass = if Float32Array? then Float32Array else Array

class @Point extends superclass
  constructor: (x,y) ->
    @[0] = x
    @[1] = y

Затем я импортировал модуль в консоль:

coffee> point = require './point'
{ Point: { [Function: Point] __super__: [ constructor: [Object], first: [Function] ] },
 Float32Array: { [Function: Float32Array] __super__: [] } }

и создал Point:

 coffee> p = new point.Point 3, 2
 [ 3, 2 ]

Этот Point имеет метод first() из Float32Array:

 coffee> p.first()
 3

и instanceof говорят, что это тоже экземпляр Float32Array:

coffee> p instanceof point.Float32Array
true

Так что я держу пари, new Point x, y возвращает экземпляр Float32Array. Конечно, это тоже экземпляр Point, и это не проблема, потому что Point является Float32Array, для использования классического выражения ООП.

1 голос
/ 14 сентября 2011

Вы должны использовать new для создания экземпляра объекта:

p = new Euclidean2D.Point(1.0,2.0)

Если вы хотите вернуть массив из конструктора, сделайте это явно:

constructor: (x,y) -> 
  return if Float32Array? then Float32Array([x,y]) else Array(x,y)

(по умолчаниюCoffeescript не возвращает значения из конструктора, поэтому вы должны сделать это явно.)


Вы тоже могли бы сделать это:

class @Point
  constructor: (x,y) ->
    @[0] = x
    @[1] = y    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...