Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no way of getting constructor name #714

Closed
frank06 opened this issue Sep 24, 2010 · 17 comments
Closed

no way of getting constructor name #714

frank06 opened this issue Sep 24, 2010 · 17 comments

Comments

@frank06
Copy link

frank06 commented Sep 24, 2010

I believe it's currently not possible to obtain a class' constructor name.

I'd like to do the following:

class Persistence
  save: () =>
    # apply some string manipulation wizardry and persist to database
    console.log "Saving #{extractTableName @constructor.toString()}"

class Animal extends Persistence
class Horse extends Animal

(new Animal).save()
(new Horse).save()

Right now @constructor.toString() will not yield the name because the constructor is an anonymous function assigned to a variable - and therefore doesn't have a name.

Would it be feasible to name the constructor function, in addition to the assignment, like so?

Horse = function Horse() {
  return Animal.apply(this, arguments);
};
@michaelficarra
Copy link
Collaborator

I do recall someone bringing up a scoping issue regarding this in another issue, but I can't seem to remember which one. If #640 (executable class bodies) is ever implemented, my proposal should fix this problem.

@zmthy
Copy link
Collaborator

zmthy commented Sep 26, 2010

Yeah. We had this and it was really cool, but there's a bug in IE6 with scoping when you have a named function, so it was removed.

@frank06
Copy link
Author

frank06 commented Sep 26, 2010

@michaelficarra: Cool, i'll be following #640 (+1 to executable class bodies)

@Tesco: Aww. I hate IE6 even more.

I really hope this gets reintroduced into coffee.

@StanAngeloff
Copy link
Contributor

We shouldn't seriously support IE6 any more, should we? I mean the beast is 9 years old and the last time I recall seeing someone even in a corporate environment using it was two or three years ago. Time to move on... I wonder if IE7 still has the leaky implementation of named functions.

@zmthy
Copy link
Collaborator

zmthy commented Sep 27, 2010

Sadly, yes.

It's also quite sad that even last version of JScript — 5.8 — used in Internet Explorer 8, still exhibits every single quirk described below.
http://kangax.github.com/nfe/

@zmthy
Copy link
Collaborator

zmthy commented Sep 27, 2010

I've had a crack at a fix for this. #729
Haven't tested if it fixes the IE problem, but it should do because it ensures the constructor is always a declaration and never an expression.

@danielribeiro
Copy link

This and proposals that solve this have been discussed and shot down way too many times (add #684, #675 do the list)

Using the createDisplayName function on #675, tweaked to check if the variable is a prototype and its prototype is not empty, will actually name all classes. Coffescript or not. On the example, "clas.includes && clas.includes(JS.Kernel)" check is for JS.Class only.

@sstephenson
Copy link
Contributor

Here's an idea. CoffeeScript can call the extended hook with a second argument—the subclass' identifier as a string. Then you can write a base class and keep track of subclasses' names however you want.

Implemented here: http://github.com/sstephenson/coffee-script/compare/extended-child-name

@danielribeiro
Copy link

Great and simple tweak sstephenson. I'd normally argue that explicitely requiring to sublcass a base class is a problem, however, this is not so on my project (most classes already have to extend a base class).

@jashkenas
Copy link
Owner

I've merged in a variant of Tesco's fix for class names, and you can now access the "name" property of the constructor function, at the cost of having slightly more verbose compiled output... closing the ticket.

@frank06
Copy link
Author

frank06 commented Oct 5, 2010

Great! Will start using it asap.

@jashkenas
Copy link
Owner

Sorry folks, I had to revert this commit because (surprise, surprise) it didn't work in Internet Explorer. Things are back as before on master at the moment.

@jashkenas
Copy link
Owner

And one more update. Tesco was quite right about the pure-function-declaration-ness being critical for IE to work. Here's a patch that puts it back that way, and works in internet explorer:

http://github.com/jashkenas/coffee-script/commit/acc06d772a731e65abdd572c9c5a0e452712df5f

@danielribeiro
Copy link

I've been working around by using the plugin mechanism, and changing the source code. On 0.9.5, function.name should work ok. With one caveat. function.name is non-standard, and will not work on IE. Guess I'll still stick with metaprogramming to make coffeescript do things they way I wish it did.

@satyr
Copy link
Collaborator

satyr commented Nov 24, 2010

@danielribeiro: Coco amends that problem by explicitly setting name.
$ coco -bpe 'class C'
var C;
C = (function(){
function C(){} C.name = "C";
return C;
}());

@ghost
Copy link

ghost commented Oct 11, 2011

This can be achieved with a base class if required, it uses a RegExp which isn't ideal but should work in IE.

class Base
  @getName: ->
    this.toString().match(/^function\s(.+)\(/)[1]

class Foo extends Base

alert Base.getName() # alerts 'Base'
alert Foo.getName()  # alerts 'Foo'

@gavJackson
Copy link

(For future Googlers...)

Expanding on soniciqs answer above, here's how I determine the class name in IE without base classing:

if clazz.constructor.name?
    classRef = clazz.constructor.name
else
    classRef = clazz.constructor.toString().match(/^function\s(.+)\(/)[1]

This can be single-lined (if thats the way you roll) to:

classRef = if command.constructor.name? then command.constructor.name else command.constructor.toString().match(/^function\s(.+)\(/)[1]

jalopezsilva added a commit to academical-inc/planner-app that referenced this issue Jun 30, 2015
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants