Search code examples
coffeescriptinformation-hiding

Hiding Internal State of CoffeeScript Object


Looking at the following from CoffeeScript Ristretto:

QueueMaker = ->
  do (queue = undefined) ->
    array: []
    head: 0
    tail: -1
    pushTail: (value) ->
      queue.array[tail += 1] = value
    pullHead: ->
      unless queue.isEmpty()
        do (value = queue.array[queue.head]) ->
          queue.array[queue.head] = undefined
          queue.head += 1
          value
      isEmpty: ->
        queue.tail < queue.head

It's possible to mutate queue.head - http://jsfiddle.net/VQLNG/.

queue = QueueMaker()
queue.head = 666
console.log queue

How can I write the above function so that head isn't public?


Solution

  • JavaScript doesn't have private properties so CoffeeScript doesn't have them either.

    However, you can simulate private properties in many cases by using function scopes to hide things and closures to access the hidden things.

    A simple stack implementation should demonstrate the technique:

    Stack = ->
        stack = [ ]
        push: (e) -> stack.push(e)
        pop:      -> stack.pop()
        toArray:  -> stack.slice()
    

    stack is a local variable in the Stack function so it cannot be accessed or seen from outside Stack. The push and pop functions simply proxy to the stack array and the toArray function is the only way to see what stack looks like. Only those three functions have access to stack so it is effectively private and each time you call Stack, you get a new local stack.

    Demo: http://jsfiddle.net/ambiguous/C8V5R/

    Adapting your queue to use this technique to hide array, head and tail is left as an exercise.