简体   繁体   中英

CoffeeScript: How to return a array From class?

What is wrong in this class in CoffeeScript ??

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

I want it to behave like:

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

But testing with Jasmine I get "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

Is there an error in CoffeeScript or in Jasmine ??

Also all of it is in a module like:

@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

In the Chrome Console I get:

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

EDIT: , again.. sorry

Has solved using an combination of @brandizzi and @arnaud576875 answers. The @module prposed in the official CoffeeScript Wiki did not work. The result is:

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

You should use new to instantiate the object:

p = new Euclidean2D.Point(1.0,2.0)

If you want to return an Array from the constructor, do it explicitly:

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

(By default, Coffeescript doesn't return values from the constructor, so you have to do it explicitly.)


You could have done that, too:

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

You are defining a constructor but expecting that it behaves like a function. The constructor, however, just sets values in the object to be returned. Since your constructor does not set any attributes in the initializing object, it really does not useful.

You have some alternatives:

  1. Initialize the class as @amaud sugested.

  2. Returns the value from the constructor as @amaud sugested (which does not make much sense to me. This is not the function of a constructor as I feel it. In this case the solution #3 seems better).

  3. define a function instead of a class. IMHO, is the most simple and functional solution

     @Point = (x, y) -> if Float32Array? then Float32Array([x,y]) else Array(x,y) 
  4. If you want Point to be either a specialization of Float32Array or Array , use the option #1 but make Point to inherit from the class you want:

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

EDIT : @amaud676875 posted an interesting question as a comment. Since a reasonable answer would involve some code, I am posting the answer as a edit.

@amaud, for verifying your point, I wrote the following CoffeeScript module:

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

Then I imported the module in the console:

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

and created a Point :

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

This Point has the first() method from Float32Array :

 coffee> p.first()
 3

and instanceof says it is an instance of Float32Array , too:

coffee> p instanceof point.Float32Array
true

So I bet new Point x, y returns an instance of Float32Array . Of course it is an instance of Point , too, and it is not a problem because Point is-a Float32Array , to use a classical OOP expression.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM