Ever wanted to make a TclOO method, yet found doing it in Tcl just a bit awkward (perhaps because it requires access to some low level API that would suck to do in Tcl directly)? This page is for you. **Writing a Method** ***The Implementation Function*** First, we need a method function. ======c static int ExampleMethod( ClientData clientData, /* Same as usual for commands. */ Tcl_Interp *interp, /* Interpreter context. */ Tcl_ObjectContext context, /* The object/call context. */ int objc, /* Number of arguments. */ Tcl_Obj *const *objv) /* The actual arguments. */ { /* * Get the object instance we're applied to. */ Tcl_Object object = Tcl_ObjectContextObject(context); /* * Get the number of arguments to "skip" when doing argument parsing. * If we did this for ordinary Tcl commands, the # skipped args would be 1 for the * command name, but we need to subtract a *VARIABLE* number of arguments since * we can be called as [$obj exampleName …] and also as [next …] from a subclass. * * The context knows what's really going on, so we ask it. */ const int skip = Tcl_ObjectContextSkippedArgs(context); if (objc - skip != 2) { Tcl_WrongNumArgs(interp, skip, objv, "foo bar"); return TCL_ERROR; } /* * Usual argument parsing. Note the offset from 'skip'. */ int foo, bar; if (Tcl_GetIntFromObj(interp, objv[skip+0], &foo) != TCL_OK || Tcl_GetIntFromObj(interp, objv[skip+1], &bar) != TCL_OK) { return TCL_ERROR; } /* * I'll skip the rest; it's usual API usage now… */ return TCL_OK; } ====== ***The Method Type Descriptor*** Next, we need a method definition record. ======c static Tcl_MethodType exampleMethodType = { /* Allow future versioning. */ TCL_OO_METHOD_VERSION_CURRENT, /* The name of the method TYPE; useful when debugging. */ "exampleMethod", /* The implementation function. */ ExampleMethod, /* The function for deleting the clientData, or NULL for "don't bother". */ NULL, /* The function for copying the clientData, or NULL for "mustn't copy". */ NULL }; ====== ***Installing the Method*** Finally, we can register the method on a class and at the same time set up a `clientData` if necessary (not this time, but very useful for standard methods which are all the same type). ======c Tcl_Class cls = …; Tcl_Obj *nameObj = Tcl_NewStringObj("example", -1); Tcl_IncrRefCount(nameObj); Tcl_NewMethod(interp, cls, nameObj, 1, &exampleMethodType, (ClientData) NULL); Tcl_DecrRefCount(nameObj); ====== **Notes** The API is a bit more complicated than for Tcl commands, though it's as simple as possible. You can also register a method on an individual instance object using `Tcl_NewInstanceMethod`, and the `1` in the call above is whether the method is public (`1`) or private (`0`). <>TclOO