the Tcl command upvar allows call by reference for actual parameters, e.g.:
proc func {a} {
upvar $a aa
lappend aa d e f
}
set l {1 2 3 a b c}
func l
My question: how do you implement the same behavior in C as a
Tcl-extension? I.e., 'func' is a command that is registered with
Tcl_CreateObjCommand(). My problem is that I don't know what arguments I
need to pass to Tcl_UpVar() since there are no names for the formal
parameters.
TIA,
Arno
You probably don't have to.
[upvar] makes links between variables in different Tcl variable
contexts. Each evaluation of a [proc] in Tcl creates a new context
for the local variables of that [proc]. [upvar] lets you associate a
variable in that local context with a variable in the caller's context.
When a Tcl command registered with Tcl_Create(Obj)Command() is
evaluated, there is no creation of such a new local variable context.
Instead, any C calls that operate on variables (Tcl_SetVar(), etc.)
operate in the current context [*]. There really is no "caller"
context, because there is no [proc], so there is no new context to
push on the context stack. Just operate on the variables, and things
should act as you wish.
Of course, if you *want* a new context, you can code up your command
procedure to provide one using another set of Tcl C routines. Look
at how Tcl [proc]s do that for examples.
[*] ...by default. Of course flag values like TCL_GLOBAL_ONLY, etc.
can modify things, but the docs tell you that.
--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|
thanks for your reply. What you write makes sense, but I have trouble to
get it to work. When I try to modify an argument passed via Tcl_Obj*
objv[], I get the error "Tcl_ListObjAppendElement called with shared
object" (I try to append an element to a list passed as the actual
parameter).
The docs say that I need to duplicate the object before modifying it,
but this is exactly what I don't want to do for call by reference.
What now?
Arno
Yes, in your command procedure registered with Tcl_CreateObjCommand()
you do need to respect the copy-on-write semantics of Tcl_Obj's.
See http://mini.net/tcl/1192.html for an illustrative example
that also indicates a situation where you may be able to avoid
unnecessary Tcl_DuplicateObj() calls.
Ultimately, though, if you need it, you need it.
set l {1 2 3 a b c}
set a $l # This makes a copy of the list reference (does NOT copy the list data)
func l # where you modify the contents of list l, say for example it is changed to
{3 2 1 a b c}
set l
=> 3 2 1 a b c
# Then if you did
set a
=> 3 2 1 a b c # opps, didn't really want a to change too!
#hence the Tcl_DuplicateObj
Tom Wilkason
Don Porter wrote:
> See http://mini.net/tcl/1192.html for an illustrative example
That is exactly what I was looking for!
Thanks a bunch,
Arno
Technically you get a copy of the list itself, and the objects contained
in the list have their reference counts incremented.
Donal.
--
Donal K. Fellows http://www.cs.man.ac.uk/~fellowsd/ fell...@cs.man.ac.uk
-- Short attention span since- ooh! Shiny thing on the floor!
-- Chad R. Orzel <orz...@earthlink.net>