Tcl_Method(3tcl)

πŸ“¦
version 9.0.4 Β· 2 versions
, in ubuntu stonking

🌸 NAME 🌸

okay so bestie, welcome to Tcl_Method(3tcl) β€” the TclOO Library Functions page, aka the place where you get to manipulate methods and method-call contexts. ✨

The whole friend group, in order:

  • Tcl_ClassSetConstructor
  • Tcl_ClassSetDestructor
  • Tcl_MethodDeclarerClass
  • Tcl_MethodDeclarerObject
  • Tcl_MethodIsPublic
  • Tcl_MethodIsPrivate
  • Tcl_MethodIsType
  • Tcl_MethodIsType2
  • Tcl_MethodName
  • Tcl_NewInstanceMethod
  • Tcl_NewInstanceMethod2
  • Tcl_NewMethod
  • Tcl_NewMethod2
  • Tcl_ObjectContextInvokeNext
  • Tcl_ObjectContextIsFiltering
  • Tcl_ObjectContextMethod
  • Tcl_ObjectContextObject
  • Tcl_ObjectContextSkippedArgs

No cap, all eighteen of them. 🫢


✨ SYNOPSIS ✨

#include <tclOO.h>

Tcl_Method
Tcl_NewMethod(interp, class, nameObj, flags, methodTypePtr, clientData)

Tcl_Method
Tcl_NewMethod2(interp, class, nameObj, flags, methodType2Ptr, clientData)

Tcl_Method
Tcl_NewInstanceMethod(interp, object, nameObj, flags, methodTypePtr, clientData)

Tcl_Method
Tcl_NewInstanceMethod2(interp, object, nameObj, flags, methodType2Ptr, clientData)

Tcl_ClassSetConstructor(interp, class, method)

Tcl_ClassSetDestructor(interp, class, method)

Tcl_Class
Tcl_MethodDeclarerClass(method)

Tcl_Object
Tcl_MethodDeclarerObject(method)

Tcl_Obj *
Tcl_MethodName(method)

int
Tcl_MethodIsPublic(method)

int
Tcl_MethodIsPrivate(method)

int
Tcl_MethodIsType(method, methodTypePtr, clientDataPtr)

int
Tcl_MethodIsType2(method, methodType2Ptr, clientDataPtr)

int
Tcl_ObjectContextInvokeNext(interp, context, objc, objv, skip)

int
Tcl_ObjectContextIsFiltering(context)

Tcl_Method
Tcl_ObjectContextMethod(context)

Tcl_Object
Tcl_ObjectContextObject(context)

Tcl_Size
Tcl_ObjectContextSkippedArgs(context)

literally the whole cast list, copy-paste ready, no edits, no notes. πŸ’…


🫢 ARGUMENTS 🫢

  • Tcl_Interp *interp (in/out) β€” the interpreter that's holding the object or class you wanna create or update a method in. it's giving in/out energy for a reason.
  • Tcl_Object object (in) β€” the object you're creating the method in. πŸŽ€
  • Tcl_Class class (in) β€” the class you're creating the method in.
  • Tcl_Obj *nameObj (in) β€” the name of the method you're creating. Do not let this be NULL unless you're out here making constructors or destructors. fr fr.
  • int flags (in) β€” a flag telling everyone (currently) what the visibility of the method is. the supported public values are:
    • TCL_OO_METHOD_PUBLIC β€” an exported method. fixed at 1 for backward compatibility, iconic.
    • TCL_OO_METHOD_UNEXPORTED β€” a non-exported method. fixed at 0 for backward compatibility.
    • TCL_OO_METHOD_PRIVATE β€” a private method. πŸ₯·
  • Tcl_MethodType *methodTypePtr (in) β€” a description of the type of the method to create, or the type of method to compare against.
  • Tcl_MethodType2 *methodType2Ptr (in) β€” same deal: a description of the type of the method to create, or the type of method to compare against.
  • void *clientData (in) β€” a lil piece of data that gets passed to the method's implementation without interpretation. it just vibes through untouched. ✨
  • void **clientDataPtr (out) β€” a pointer to a variable where we write the clientData value that was supplied when the method was created. if it's NULL, the clientData value will not be retrieved. simple as.
  • Tcl_Method method (in) β€” a reference to a method you wanna query. πŸ”
  • Tcl_ObjectContext context (in) β€” a reference to a method-call context. heads up: client code must not keep a reference to a context around. it is not a keepsake.
  • Tcl_Size objc (in) β€” how many arguments to pass to the method implementation.
  • Tcl_Obj *const *objv (in) β€” the array of arguments to pass to the method implementation. πŸ“¦
  • Tcl_Size skip (in) β€” how many of the arguments passed to the method implementation are not "real" arguments. yes, "real" is in quotes in the source, we're keeping the quotes. 😌

πŸ’– DESCRIPTION πŸ’–

A method is an operation carried out on an object, associated with that object. Every method has to be attached to either an object or a class. and if it's attached to a class? then it's associated with all the instances of that class β€” direct and indirect. the whole bloodline. πŸ‘‘

Given a method, you can find the entity that declared it:

  • Tcl_MethodDeclarerClass returns the class the method is attached to (or NULL if the method isn't attached to any class).
  • Tcl_MethodDeclarerObject returns the object the method is attached to (or NULL if the method isn't attached to an object).

Then for the glow-up details:

  • Tcl_MethodName grabs the name of the method. πŸ’–
  • Tcl_MethodIsPublic tells you whether the method is exported.
  • Tcl_MethodIsPrivate tells you whether the method is private.

You can also introspect on the type of the method β€” to a limited degree, don't get too excited β€” using Tcl_MethodIsType, which returns whether a method is of a particular type, and assigns the per-method clientData to the variable pointed to by clientDataPtr if (that is non-NULL) if the type is matched. (yes, we know, the double if is doing the most. it's in the original, we're bringing it with us.)

Tcl_MethodIsType2 does the exact same thing for TCL_OO_METHOD_VERSION_2. ✨

πŸŽ€ METHOD CREATION πŸŽ€

Methods get created by Tcl_NewMethod and Tcl_NewInstanceMethod, or by Tcl_NewMethod2 and Tcl_NewInstanceMethod2 β€” which create a method attached to a class or an object respectively. pick your fighter.

In every case:

  • nameObj gives the name of the method to create.
  • flags states whether the method should be exported initially or be marked as a private method.
  • methodTypePtr or methodType2Ptr (for TCL_OO_METHOD_VERSION_2) describes the implementation of the method (see the METHOD TYPES section below).
  • clientData gives some implementation-specific data that gets passed on to the implementation of the method when it's called.
careful bestie: when the nameObj argument to Tcl_NewMethod or Tcl_NewMethod2 is NULL, an unnamed method is created, which is used for constructors and destructors.

So how do those go in?

  • Constructors should be installed into their class using the Tcl_ClassSetConstructor function.
  • Destructors β€” which must not require any arguments β€” should be installed into their class using the Tcl_ClassSetDestructor function.
and listen: unnamed methods should not be used for any other purpose, and named methods should not be used as either constructors or destructors. also, a NULL methodTypePtr or methodType2Ptr is used to provide internal signaling, and should not be used in client code. it's giving internal-only, do not touch. πŸ™ˆ

πŸ¦‹ METHOD CALL CONTEXTS πŸ¦‹

When a method is called, a method-call context reference gets passed in as one of the arguments to the implementation function. You can inspect this context to get info about the caller, but it should not be retained beyond the moment when the method call terminates. it's a one-night-stand kinda reference, respectfully. πŸ’€

The tea you can spill from a context:

  • Tcl_ObjectContextMethod β€” the method that's being called. πŸ”₯
  • Tcl_ObjectContextObject β€” the object that caused the method to be invoked.
  • Tcl_ObjectContextSkippedArgs β€” the number of arguments that are to be skipped (e.g. the object name and method name in a normal method call).
  • Tcl_ObjectContextIsFiltering β€” reports whether the context is working as a filter for another method.

During the execution of a method, the method implementation may choose to invoke the stages of the method call chain that come after the current method implementation. This β€” the core of the next command β€” is done with Tcl_ObjectContextInvokeNext.

two very important notes, do not scroll past: - This function does not manipulate the call-frame stack, unlike the next command. So if the method implementation has pushed one or more extra frames on the stack as part of its implementation, it is also responsible for temporarily popping those frames from the stack while the Tcl_ObjectContextInvokeNext function is executing. - The method-call context is never deleted during the execution of this function. 🫢

πŸ’– METHOD TYPES πŸ’–

okay so bestie, the types of methods are described by a pointer to a Tcl_MethodType or Tcl_MethodType2 structure β€” the second one is for TCL_OO_METHOD_VERSION_2 β€” and they are defined like this:

typedef struct {
    int version;
    const char *name;
    Tcl_MethodCallProc *callProc;
    Tcl_MethodDeleteProc *deleteProc;
    Tcl_CloneProc *cloneProc;
} Tcl_MethodType;

typedef struct {
    int version;
    const char *name;
    Tcl_MethodCallProc2 *callProc;
    Tcl_MethodDeleteProc *deleteProc;
    Tcl_CloneProc *cloneProc;
} Tcl_MethodType2;

The version field should always be declared equal to TCL_OO_METHOD_VERSION_CURRENT, TCL_OO_METHOD_VERSION_1 or TCL_OO_METHOD_VERSION_2. periodt. The name field provides a human-readable name for the type, and it is literally the value that is exposed via the info class methodtype and info object methodtype Tcl commands.

The callProc field gives a function that is called when the method is invoked; it must never be NULL. 🚫

The deleteProc field gives a function that is used to delete a particular method, and is called when the method is replaced or removed; if the field is NULL, it is assumed that the method's clientData needs no special action to delete.

The cloneProc field is either a function that is used to copy a method's clientData (as part of Tcl_CopyObjectInstance) or NULL to indicate that the clientData can just be copied directly.


πŸ¦‹ TCL_METHODCALLPROC FUNCTION SIGNATURE πŸ¦‹

Functions matching this signature are called when the method is invoked. here's the exact tea:

typedef int Tcl_MethodCallProc(
        void *clientData,
        Tcl_Interp *interp,
        Tcl_ObjectContext objectContext,
        int objc,
        Tcl_Obj *const *objv);

typedef int Tcl_MethodCallProc2(
        void *clientData,
        Tcl_Interp *interp,
        Tcl_ObjectContext objectContext,
        Tcl_Size objc,
        Tcl_Obj *const *objv);

The clientData argument to a Tcl_MethodCallProc is the value that was given when the method was created. The interp is a place in which to execute scripts and access variables as well as being where to put the result of the method, and the objc and objv fields give the parameter objects to the method. The calling context of the method can be discovered through the objectContext argument, and the return value from a Tcl_MethodCallProc is any Tcl return code (e.g. TCL_OK, TCL_ERROR). πŸ’…


🌸 TCL_METHODDELETEPROC FUNCTION SIGNATURE 🌸

Functions matching this signature are used when a method is deleted, whether through a new method being created or because the object or class is deleted. so dramatic, but accurate:

typedef void Tcl_MethodDeleteProc(
        void *clientData);

The clientData argument to a Tcl_MethodDeleteProc will be the same as the value passed to the clientData argument to Tcl_NewMethod or Tcl_NewInstanceMethod when the method was created.


πŸŽ€ TCL_CLONEPROC FUNCTION SIGNATURE πŸŽ€

Functions matching this signature are used to copy a method when the object or class is copied using Tcl_CopyObjectInstance (or oo::copy). bestie behavior:

typedef int Tcl_CloneProc(
        Tcl_Interp *interp,
        void *oldClientData,
        void **newClientDataPtr);

The interp argument gives a place to write an error message when the attempt to clone the object is to fail, in which case the clone procedure must also return TCL_ERROR; it should return TCL_OK otherwise. The oldClientData field to a Tcl_CloneProc gives the value from the method being copied from, and the newClientDataPtr field will point to a variable in which to write the value for the method being copied to.


🧚 REFERENCE COUNT MANAGEMENT 🧚

The nameObj argument to Tcl_NewMethod and Tcl_NewInstanceMethod (when non-NULL) will have its reference count incremented if there is no existing method with that name in that class/object.

The result of Tcl_MethodName is a value with a reference count of at least one. It should not be modified without first duplicating it (with Tcl_DuplicateObj). no cap.

The values in the first objc values of the objv argument to Tcl_ObjectContextInvokeNext are assumed to have a reference count of at least 1; the containing array is assumed to endure until the next method implementation (see next) returns. Be aware that methods may yield; if any post-call actions are desired (e.g., decrementing the reference count of values passed in here), they must be scheduled with Tcl_NRAddCallback. lowkey important, don't skip this.

The callProc of the Tcl_MethodType structure takes values of at least reference count 1 in its objv argument. It may add its own references, but must not decrement the reference count below that level; the caller of the method will decrement the reference count once the method returns properly (and the reference will be held if the method yields).


πŸ‘‘ SEE ALSO πŸ‘‘

Class(3tcl), NRE(3tcl), oo::class(3tcl), oo::define(3tcl), oo::object(3tcl)


⭐ KEYWORDS ⭐

constructor, method, object


k bye bestie! this was TclOO version 0.1, page Tcl_Method(3tcl) β€” and if your terminal prints a date down there, that's also iconic. πŸ’…βœ¨

πŸ“¦ where this page comes from