I have the following code
class Foo
a: ->
console.log arguments.callee.name
b: ->
@a()
c: ->
@a()
f = new Foo
f.b() #=> should output 'b'
f.c() #=> should output 'c'
Here's a use case
class Something extends Stream
foo: ->
_helper 'foo', 'a', 'b', 'c'
bar: ->
_helper 'bar', 'my neighbor totoro'
dim: ->
_helper 'dim', 1, 2, 3
sum: ->
_helper 'sum', 'hello', 'world'
_helper: (command, params...) ->
@emit 'data', command, params...
something = new Something
something.foo()
something.bar()
# ...
I don't want to have to duplicate sending the method name for each call to my private _helper method
So to be clear, I think the second way you have it is totally reasonable and is the way to go.
But to answer your question, you can generate each function dynamically to avoid having to retype the commands.
class Foo
commands =
foo: ['a', 'b', 'c']
bar: ['my neighbor totoro']
dim: [1,2,3]
for own name, args of commands
Foo::[name] = ->
@emit 'data', name, args...
and assuming you want the functions to useful stuff, you can still use functions.
// ...
commands =
foo: (args...) -> return ['a', 'b', 'c']
// ...
for own name, cb of commands
Foo::[name] = (command_args...) ->
args = cb.apply @, command_args
@emit 'data', name, args...
This is what I would have done:
class Something extends Stream
constructor: ->
@foo = helper.bind @, "foo", "a", "b", "c"
@bar = helper.bind @, "bar", "my neighbor totoro"
@dim = helper.bind @, "dim", 1, 2, 3
@sum = helper.bind @, "sum", "hello", "world"
helper = (command, params...) ->
@emit 'data', command, params...
The advantages of this method are:
helper function is a private variable. It can't be accessed directly via an instance.helper function is only declared once and is shared between all instances.foo, bar, dim and sum are partial applications of helper. Hence they don't consume more memory for the function body.Edit: An even cleaner approach would be:
class Something extends Stream
constructor: ->
@foo = @emit.bind @, "data", "foo", "a", "b", "c"
@bar = @emit.bind @, "data", "bar", "my neighbor totoro"
@dim = @emit.bind @, "data", "dim", 1, 2, 3
@sum = @emit.bind @, "data", "sum", "hello", "world"
Sure, it's a little redundant but you can't expect more from a language like JavaScript. It's not Factor. However it is readable, clean, easily understandable, and above all - correct.