bgoodr
bgoodr

Reputation: 2930

How to dynamically add methods to a class in [incr-tcl]

In Incr Tcl, I receive a gain in programming productivity via changing and then re-eval'ing a class's methods into a running Tcl interpreter, without restarting the application. To do that, I have to define the methods outside of the class definition using the body syntax, and re-eval the body definition into the running Tcl interpreter. That works fine. Astonishingly, and apparently by design, in Incr Tcl,

A class can only be defined once, although the bodies of class methods and procs can be defined again and again for interactive debugging.

Naturally during development, however, I am splitting methods (refactoring) into two or more additional methods to be defined in the same class.

I would like to find a way to forcibly add methods to an existing class in a running Tcl interpreter:

  1. Without deleting and re-eval'ing the class definition into that running Tcl interpreter,
  2. Without restarting the Tcl application that contains the existing object instances of the Incr Tcl classes to be augmented, and
  3. Without the result that the existing objects are deleted from said Tcl interpreter.

I need this exclusively as a development/debugging ritual, not for production code (i.e., I don't need to dynamically add methods programmatically). I will entertain slimy, evil, back-door answers. Changing the production copy of Incr Tcl to add additional behavior is not practical, as the binaries of Incr Tcl I have to use are, unfortunately, statically bound into the running process and can't be unloaded and reloaded via some shared library witchcraft.

Upvotes: 0

Views: 523

Answers (1)

Donal Fellows
Donal Fellows

Reputation: 137587

You can redefine a method in a class with itcl::body:

itcl::body helloworld::greet {} {
    puts "Goodbye Cruel World from $owner"
}

However, you can't add a wholly-new method to a class that way. Well, certainly not in 3.4 (I've not tested with 4.0):

% package require Itcl
3.4
% itcl::class hi {
    # Nobody in here but us chickens...
}
% hi Hi
Hi
% itcl::body hi::there {} {puts "Howdy!"}
function "there" is not defined in class "::hi"

If you need that sort of functionality, you might consider using XOTcl or (from Tcl 8.5 onwards) TclOO, both of which support complete reconfiguration of classes after creation.

Upvotes: 2

Related Questions