View · Search · Index
No registered users in community xowiki
in last 10 minutes

Re: [Xotcl] Changing a parameter's -setter function

From: Scott Gargash <scottg_at_atc.creative.com>
Date: Thu, 16 Mar 2006 03:25:20 -0700

Thanks for your time and patience in answering my questions.

Gustaf Neumann <neumann_at_wu-wien.ac.at> wrote on 03/15/2006 02:46:58 AM:

> Scott Gargash schrieb:
> >
> > Hello,
> >
> > Is it possible to change the -setter command associated with a
> > parameter at some point other than class definition?
> >
> one can use the method "parameter" at any time to add/redefine
> parameters (see below).

The issue with using the "parameter" method is that it changes the parameter definition class-wide,
which is undesireable. I'd like to change a parameters -setter property on a per-instance basis.
The intended class behavior is to use the default setter class wide at construction time, but after
an instance is fully constructed, each instance should use an overridden -setter. Ideally the per
instance -setter is directed to a instproc class.

Right now I have define the -setter property and have an instproc for the class that does the
standard behavior, but then in the constructor I define a "[self] proc" to redefine the
implementation of the -setter for that instance.

# This is what I do currently
Class create A -parameter {{foo -setter myfoo}}
A instproc init {args} {
  # [self] is valid so revector [my setfoo] to have sideeffects
  [self] proc myfoo {p v} {
    my set $p $v
    #do side-effects
  }
}
# no side effects at construction time
A instproc myfoo {p v} {my set $p $v}

This works (I get the behavior I desire), but it means I have to 1) define a proc that duplicates
the default behavior and 2) construct n identical copies of the implementation for the -setter proc,
when really I can get by with the default behavior and one copy of the override behavior shared
across all instances, just revectored the setter behavior once it's safe to do so.

# What I'd prefer
Class create A -parameter {foo}
A instproc init {args} {
  # [self] is valid, revector [self]'s foo setter from default to the side-effectful variant
  [self] parametercmd {foo -setter myfoo}
}
A instproc myfoo {p v} {
  my set $p $v
  # do side effects
}

Besides being more memory efficient, it seems to more clearly express my intent. As you say, a trace
would work, but traces tend to look and feel a bit like magic.

> the difference in speed is due to the fact that the default
> setter/getter method is implemented in C,
> whereas the tailored functions are in tcl. it is certainly possible to
> program a tailored getter method
> in C as well, but i doubt that this is worth the effort.

As you may have inferred from my questions, performance is an issue for my application. I'm hoping
to avoid having to drop into C (and XOTcl's native performance gives me hope, especially relative to
snit), but I'm prepared to move to C if and when I have to.

I've seen the part of the tutorial about wrapping C-extensions with XOTcl, but is there a
reference/tutorial for extending XOTcl in C? How would I go about reimplementing a method in C?
Can I just use the vanilla Tcl API or do I need to compile/link against XOTcl also?

One thing that has confused me so far is the "namespace on demand" concept. Where are instance
variables stored if not in a namespace?

% Object a
::a
% a set foo 123
123
% namespace exists a
0

Where does Object a's foo variable reside?

If I wanted to implement a method as a C function, how does the C function find the value of "[a set
foo]" via the Tcl API? I.e., what would I pass as the varname to Tcl_GetVar()? Or do I need XOTcl's
C API to look it up? Where do I install my C commands such that they are found automatically by
XOTcl's method lookup alogrithm?

Is this sort of info spec'd by XOTcl or is it implementation defined? Is this what
"requireNamespace" does? I've read the docs but I haven't really grokked it yet.

      Scott