Reputation: 41909
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?
Upvotes: 0
Views: 100
Reputation: 231385
QueueMaker = ->
do (array = [], head = 0, tail = -1) ->
pushTail: (value) ->
array[tail += 1] = value
pullHead: ->
if tail >= head
do (value = array[head]) ->
array[head] = undefined
head += 1
value
isEmpty: ->
tail < head
With this version, array
, head
and tail
are hidden. They are initialed when the queue
is created, and remain in existence only as long as it exists.
coffee> queue = QueueMaker()
{ pushTail: [Function],
pullHead: [Function],
isEmpty: [Function] }
coffee> queue.head
undefined
But to be honest, this is the first version of QueueMaker
on the Ristretto link. What you gave us was the “de-encapsulate”
version, rewritten purposely to make these variables visible (in order to extend its behavior).
For reference, the "de-encapuslated" version is:
QueueMaker = ->
do (queue = undefined) ->
queue =
array: []
head: 0
tail: -1
pushTail: ...
pullHead: ...
Your question omitted the queue=
line. Now the purpose of the do()->
should be clearer.
Upvotes: 0
Reputation: 434665
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.
Upvotes: 1
Reputation: 26488
The return value of QueueMaker
is a JavaScript object, with head
being one of it's fields. Object fields are mutable, with no option for protected status.
Even with QueueMaker
rewritten as a CoffeeScript class, and head being an instance variable, it would still be mutable from outside the object scope.
CoffeeScript can only support the language level features of JavaScript, which does not support private/protected keywords. Sadly.
Upvotes: 0