How to access arguments.callee in CoffeeScript class?

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'

Question: How can I get the name of the calling function in my class?


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:

  1. The helper function is a private variable. It can't be accessed directly via an instance.
  2. The helper function is only declared once and is shared between all instances.
  3. The functions foo, bar, dim and sum are partial applications of helper. Hence they don't consume more memory for the function body.
  4. It doesn't require a loop like @loganfsmyth's answer does.
  5. It's cleaner.

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.