Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the name of a Mootools class from within

I'd like to get at the variable name of class.

var Poop = new Class({ 
    getClassName: function() { 
        return arguments.callee._owner.name;
    } 
});
var a = new Poop();
a.getClassName(); //want 'Poop'

I'm making that will be implemented into other classes, and I'd like to build a SQL query that uses the class name (pluralized) for the table.

I've tried various combinations of the above example to try to get the name, and can't figure it out (if it's even possible considering MooTools class system).

like image 878
seanmonstar Avatar asked May 08 '09 00:05

seanmonstar


2 Answers

Found a solution. Hash has a keyOf function, which will give me the variable name that holds a value. So I made a Hash of window, and then asked for the key of the class constructor.

var Poop = new Class({
    name: function() {
        var w = $H(window);
        return w.keyOf(this.constructor);
    }
});
var a = new Poop();
a.name(); // returns 'Poop'

This of course works only because I create classes in the global window namespace (as is common with MooTools). If you made classes inside some namespace, then you'd just need to Hash that namespace instead.

Edit: I wrote up about how to use this solution and how to make it work in namespaces automatically, for any MooToolers interested.

like image 180
seanmonstar Avatar answered Nov 06 '22 02:11

seanmonstar


I ran into a problem with Extends, but found a way around it:

var getClassNameFromKeys = function (obj, instance) {
        var i = 0, keys = Object.keys(obj);
        for (i; i < keys.length; i++) {
        if ('Ext' !== keys[i] && typeOf(obj[keys[i]]) === 'class' && instance instanceof obj[keys[i]]) {
                return keys[i];
            }
        }
    },
    Ext = new Class(),
    WhatsMyName = new Class({
        Extends: Ext
    }),
    whatsMyNameInstance = new WhatsMyName(),
    cName = getClassNameFromKeys(this, whatsMyNameInstance);

console.log(cName);

You can avoid the check on the extends name if you follow a pattern something like this:

var O = {},
    whatsMyNameInstance;

(function () {
    var SUBCLASS_KEYS;

    O.Ext = new Class({
        _className: null,
        getClassName: function () {
            var i = 0;

            SUBCLASS_KEYS = SUBCLASS_KEYS || Object.keys(O.subclasses);

            for (i; i < SUBCLASS_KEYS.length; i++) {
            if (this instanceof O.subclasses[SUBCLASS_KEYS[i]]) {
                    return SUBCLASS_KEYS[i];
                }
        }
        }        
    });
})();

O.subclasses = {};

O.subclasses.WhatsMyName = new Class({
    Extends: O.Ext
});

whatsMyNameInstance = new O.subclasses.WhatsMyName();

whatsMyNameInstance.getClassName();
like image 2
javascriptjedi Avatar answered Nov 06 '22 03:11

javascriptjedi