loading...

Why does (class instance).$name result in the name of the most recent classname and not the actual name?

calin92540842 profile image PDS OWNER CALIN (Calin Baenen) ・2 min read

HotTea (2 Part Series)

1) HotTea update #1.0aus 2) Why does (class instance).$name result in the name of the most recent classname and not the actual name?

So I'm working on HotTea, and I came across a weird bug, the name of a class instance will be the name of the most recently created class whether or not the instance belongs to said class, example:


test1 = Class({
    name: "test1"
});

test2 = Class({
    name: "test2"
});

test1.$name // test1 | Works like normal...
test2.$name // test2 | Yea, that's right...
test1().$name // test2 | Wait... what?

So, as the example shows, the names of the Literal function that control the creation of instances are fine, they aren't affected, but instances themselves are.
Why is it doing this? I get the names in the EXACT SAME way...
This is my code:


let Class = function Class(description=null) {
    if(typeof description !== "object" || description === null) {
        description = {};
    }
    classInstance = function classInstance() {
        const base = (
            typeof description.call === "function" &&
            !Object.isSealed(description.call) &&
            !Object.isFrozen(description.call) ?
            description.call :
            {}
        );
        let publicItems = description.public || {};
        let finalItems = description.final || {};
        for(const item of Object.keys(publicItems)) {
            base[item] = publicItems[item];
        }
        for(const item of Object.keys(finalItems)) {
            Object.defineProperty(base,item,{
                value: finalItems[item],
                writable: false
            });
        }
        base.$constructorMethod = Literal;
        base.$root = Class.symbol;
        base.$name = Literal.$name;
        return base;
    };
    let statics = description.static || {};
    let Literal = function Literal(...args) {
        let CONSTRUCTOR = description.constructor;
        let varinput = {};
        if(typeof CONSTRUCTOR === "function") {
            varinput = CONSTRUCTOR(...args);
        }
        const instance = classInstance();
        for(const s of Object.keys(statics)) {
            if(
                typeof statics[s] !== "function"
            ) instance[s] = statics[s];
        }
        if(typeof varinput === "object") {
            for(const v of Object.keys(varinput)) {
                instance[v] = varinput[v];
            }
        }
        instance.$role = "instance";
        return Object.seal(instance);
    };
    let classVars = description.class || {};
    for(const cv of Object.keys(classVars)) {
        Literal[cv] = classVars[cv];
    }
    Literal.$name = (
        typeof description.name === "string" &&
        description.name.length >= 1 ?
        description.name :
        "$CLASS$"
    );
    Literal.name = Literal.$name;
    Literal.$role = "class";
    Literal.$root = Class.symbol;
    for(const s of Object.keys(statics)) Literal[s] = statics[s];
    return Object.seal(Literal);
};

So, what's going wrong?
Why does this happen even though I get them in the same way?
And, how can I fix this?

Thanks for reading!
Cheers!

HotTea (2 Part Series)

1) HotTea update #1.0aus 2) Why does (class instance).$name result in the name of the most recent classname and not the actual name?

Posted on Jun 2 by:

calin92540842 profile

PDS OWNER CALIN (Calin Baenen)

@calin92540842

I am a 13 (as of Oct 30 of 2019) yr/o developer (I have been developing mini-projects for 4, years now, since I was 9), who makes projects in languages like: Java, HTML, Python 3, JS, CSS, and C#.

Discussion

markdown guide
 

You don't have a var/let/const in front of classInstance so it's a global window.classInstance not the closure you think it is. It's getting overwritten etc.

'use strict' can be your friend :)

 

Ah shit, why is it always the let var const thing that always trips me the fuck up?? But, how do I use strict mode? Is there any rule about where I start using strict mode? Also, tysm

 

If you stick the string

'use strict'

as the first line of a file - it's in strict mode and it should tell you that you are assigning to a global without defining it.

Other choice is use a linter like eslint can help in these circumstances.