CoffeeScript: comment renvoyer un tableau De la classe?

Qu'est-ce qui ne va pas dans cette classe dans CoffeeScript ??

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

Je veux qu'il se comporte comme:

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

Mais le test avec Jasmine reçoit "Expected undefined to equal 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 

Y a-t-il une erreur dans CoffeeScript ou dans Jasmine?

Tout cela se trouve dans un module comme:

 @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 

Dans la console Chrome, je reçois:

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

EDIT: encore une fois désolé

A résolu en utilisant une combinaison de réponses @brandizzi et @ arnaud576875. Le @module prononcé dans le Wikipédia CoffeeScript officiel n'a pas fonctionné. Le résultat est:

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

Vous devez utiliser le new pour créer une instanciation de l'objet:

 p = new Euclidean2D.Point(1.0,2.0) 

Si vous souhaitez renvoyer une matrice du constructeur, faites-le explicitement:

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

(Par défaut, Coffeescript ne renvoie pas les valeurs du constructeur, donc vous devez le faire explicitement.)


Vous auriez pu le faire aussi:

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

Vous définissez un constructeur, mais vous attendez à ce qu'il se comporte comme une fonction. Le constructeur, cependant, ne définit que des valeurs dans l'objet à renvoyer. Étant donné que votre constructeur ne définit aucun attributs dans l'objet d'initialisation, il n'est vraiment pas utile.

Vous avez quelques alternatives:

  1. Initialiser la classe comme @amaud suggéré.

  2. Renvoie la valeur du constructeur à mesure que @amaud a suggéré (ce qui n'a pas beaucoup de sens pour moi. Ce n'est pas la fonction d'un constructeur que je le sens. Dans ce cas, la solution # 3 semble mieux).

  3. Définissez une fonction au lieu d'une classe. IMHO, est la solution la plus simple et la plus fonctionnelle

     @Point = (x, y) -> if Float32Array? then Float32Array([x,y]) else Array(x,y) 
  4. Si vous souhaitez que Point soit une spécialisation de Float32Array ou Array , utilisez l'option n ° 1, mais faites Point pour hériter de la classe souhaitée:

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

EDIT : @ amaud676875 a posté une question intéressante en tant que commentaire. Comme une réponse raisonnable impliquerait un certain code, je publie la réponse comme une édition.

@amaud, pour vérifier votre point, j'ai écrit le module CoffeeScript suivant:

 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 

Ensuite, j'ai importé le module dans la console:

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

Et a créé un Point :

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

Ce Point a la first() méthode first() de Float32Array :

  coffee> p.first() 3 

Et instanceof dit que c'est une instance de Float32Array aussi:

 coffee> p instanceof point.Float32Array true 

Donc, je parie de new Point x, y renvoie une instance de Float32Array . Bien sûr, c'est une instance de Point aussi, et ce n'est pas un problème parce que Point is-a Float32Array , pour utiliser une expression OOP classique.