TIP 605: Function to get class name from object

Login
Author:         René Zaumseil <[email protected]>
State:          Final
Type:           Project
Vote:           Done
Created:        15-Jul-2021
Post-History:   
Keywords:       Tcl
Tcl-Version:    8.7
Tcl-Branch:     tip-605
Vote-Summary    Accepted 7/0/0
Votes-For:      AK, FV, JN, KBK, KW, MC, SL
Votes-Against:  none
Votes-Present:  none

Abstract

The ability to get the current class of an object is missing from the C API, due to an API oversight. This TIP is about adding that capability.

Rationale

This TIP intends to add the following public functions to Tcl:

Tcl_Class Tcl_GetClassOfObject(Tcl_Object object)

Tcl_Obj Tcl_GetObjectClassName(Tcl_Interp *interp, Tcl_Object object)

There is also currently a public function Tcl_GetObjectName to get the object name of an given Tcl_Obj. A similar function to get the class name does currently not exist. But these information is already existing in the internals of an oo object.

This was always information that should have been obtainable via the API.

C Implementation

Tcl_Obj *
Tcl_GetObjectClassName(
    Tcl_Interp * interp,
    Tcl_Object object)
{
    Tcl_Object classPtr;
    classPtr = (Tcl_Object)(((Object *)object)->selfCls->thisPtr);
    if (classPtr == NULL) return NULL;

    return Tcl_GetObjectName(interp, classPtr);
}

Donal Fellows added the following function:

Tcl_Class
Tcl_GetClassOfObject(
    Tcl_Object object)
{
    return (Tcl_Class) ((Object *) object)->selfCls;
}

Both functions are created and exported in Branch tip-605.

Discussion

The following alternative was posted by Donal Fellows on tcl-core:

I’d prefer getting the class to getting the name of the class (the name can be navigated to from there cheaply) as that makes the expensive failure-possible operations be something you can more commonly avoid, but otherwise this seems fine. We could have the name lookup you propose as well. This appears to be an area where I simply didn’t think about putting in any API.

The operation that I’m looking for is (probably; this is written from memory and I’ve not checked if it compiles):

    Tcl_Class Tcl_GetClassOfObject(Tcl_Object object) {
        return (Tcl_Class)(((Object *)object)->selfCls);
    }

Technically, the traversing of the thisPtr link is possible via Tcl_GetClassAsObject() and getting the name is the standard op. It’s the selfCls link that’s currently not exposed in the C API at all.

This discussion was resolved by adding the above function to the TIP on the grounds that having both functions is fine and they serve slightly different use-cases.

Documentation

The following documentation will be added in the Tcl_GetObjectName man page:

The function Tcl_GetObjectClassName will return the class name of an existing object. If the given object is not an class NULL is returned.

Copyright

This document has been placed in the public domain.