0

I'm trying to write a program that takes a number and validates it according to the Luhn formula.

How do I set object properties in the class in CoffeeScript? I want to do this:

class Luhn
  constructor: (@number)  ->

  lastDigit: @number % 10

But this produces:

function Luhn(number) {
  this.number = number;
}

Luhn.prototype.checkDigit = Luhn.number % 10;

Which returns undefined, because it's trying to access a class variable.

When setting the prototype, you can do this, though:

function Luhn(number) {
  this.number = number;
}

Luhn.prototype.lastDigit = function() {
  return this.number % 10
}

Now an instance of the Luhn class has a function lastDigit() which works.

Is there a way of setting object properties in the class in CoffeeScript? I know I can set it in the constructor, like this:

class Luhn
  constructor: (@number)  ->
    @lastDigit: @number % 10

But I want to set other, more complicated properties, and I don't want my constructor to become a mess. This is an idea, but it still kinda sucks:

class Luhn
  constructor: (@number)  ->
    @lastDigit: @number % 10
    @complicatedProperty1 = getComplicatedProperty1(@number)
    @complicatedProperty2 = getComplicatedProperty2(@number)

What's the best way to go about this?

1 Answer 1

1

Set them in the constructor, that's the only place where you have an instance to work with.

Alternatively, use a method instead of a simple property:

class Luhn
  constructor: (@number)  ->

  lastDigit: -> @number % 10

or:

class Luhn
  constructor: (@number)  ->

  lastDigit: -> @number % 10

  complicatedProperty1: ->
    @_complicatedProperty1 ?= getComplicatedProperty1(@number)

The caching inside complicatedProperty1 assumes that @number won't be changing and that getComplicatedProperty1(@number) won't return null or undefined.

A CoffeeScript class isn't really a C-style struct so exposing everything as plain properties isn't the best idea ever. If you need easy access to just the properties, then provide a toJSON or serialize method to do so without exposing your internals to accidental modification:

toJSON: ->
  number: @number
  lastDigit: @lastDigit()
  complicatedProperty1: @complicatedProperty1()

I used toJSON as the name as JSON.stringify will call that method when it tries to stringify an object:

If an object being stringified has a property named toJSON whose value is a function, then the toJSON method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the toJSON method when called will be serialized.

so toJSON is a natural name of serialization functions in (Coffee|Java)Script.

Sign up to request clarification or add additional context in comments.

2 Comments

is this documented anywhere? As I thought class { x: 1} would work as expected
@phil294: It sort of does work expect, for example. But note that the question is about lastDigit: @number % 10 rather than lastDigit: 6.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.