1

I have two classes and a global function. In the global function, I would like to to determine which class called it. Here is what the code looks like in CofffeeScript

window.pet = ()->
  alert "I was called #{by}"

class Cat
  constructor: (@name) ->
    pet()

class Dog
  constructor: (@name) ->
    pet()

Is this possible?

Alexis
  • 23,545
  • 19
  • 104
  • 143
  • @user1737909 Short answer: yes http://stackoverflow.com/a/14962482/1250044 – yckart Jun 02 '13 at 14:41
  • possible duplicate of [javascript - arguments.callee.toString() and arguments.callee.name does not return function name](http://stackoverflow.com/questions/1935521/javascript-arguments-callee-tostring-and-arguments-callee-name-does-not-retu) – yckart Jun 02 '13 at 14:41
  • Function.toString is not even standart. Old SpiderMonkey doesnt even have it. – Ven Jun 02 '13 at 15:59
  • @yckart: That's not needed here, since CoffeeScript constructors are named functions and the (nonstandard) `.name` property *does* work here – Bergi Jun 02 '13 at 22:56

2 Answers2

2

Short answer: don't.

This question is probably getting closed as a duplicate. But i'd like to point out that if you're needing to do this kind of trick to solve a problem, you're probably going to introduce another problem by using a trick like that. If the behaviour of a function needs to depend on something (like where is it being called from), make it explicit and use a parameter for that dependency; it's a pattern that everyone will easily understand.

pet = (pet) ->
  alert "I was called by #{pet.name} the #{pet.constructor.name}" 

class Cat
  constructor: (@name) ->
    pet @

new Cat 'Felix' # Output: "I was called by Felix the Cat"

That being said, Function#name is not standard, so you probably shouldn't use that either. But you can safely access a pet's "class" (i.e. its constructor function) by accessing its constructor property as shown in the example.

epidemian
  • 18,817
  • 3
  • 62
  • 71
0

arguments.callee.caller.name is what your looking for. The sample below should do the trick.

pet = ->
    callerName = arguments.callee.caller.name
    console.log "called by #{callerName}"

class Cat
  constructor: (@name) ->
    pet()

class Dog
  constructor: (@name) ->
    pet()

c = new Cat()
d = new Dog()
nicksweet
  • 3,929
  • 1
  • 20
  • 22
  • Note, however, that `arguments.callee` [won't be available](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode#Making_eval_and_arguments_simpler) when using the strict mode. – epidemian Jun 04 '13 at 21:07