For some reason one might need to know the type name of a Tcl object. The type name is stored in Tcl_Obj's typePtr->name. Below is the small C extension ''typeof'' to get the type name. ---- // typeof // BSD License #include #ifdef WIN32 #ifdef typeof_EXPORTS #define typeof_EXPORT __declspec(dllexport) #else #define typeof_EXPORT __declspec(dllimport) #endif #else #define typeof_EXPORT #endif static int Typeof_Cmd(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]); int typeof_EXPORT Typeof_Init(Tcl_Interp *interp) { /* * This may work with 8.0, but we are using strictly stubs here, * which requires 8.1. */ if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } if (Tcl_PkgRequire(interp, "Tcl", "8.1", 0) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "typeof", "0.1.1") != TCL_OK) { return TCL_ERROR; } Tcl_CreateObjCommand(interp, "typeof", (Tcl_ObjCmdProc *) Typeof_Cmd, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); return TCL_OK; } static int Typeof_Cmd(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const argv[]) { if (argc != 2) { Tcl_WrongNumArgs (interp, 1, argv, "object"); return TCL_ERROR; } if(argv[1]->typePtr) { Tcl_SetObjResult (interp, Tcl_NewStringObj (argv[1]->typePtr->name, -1)); } else { Tcl_SetObjResult (interp, Tcl_NewStringObj ("", -1)); } return TCL_OK; } ---- '''Usage:''' typeof object ---- !!!!!! %| Extensions |% !!!!!!