Version 1 of References to proc-local vars

Updated 2007-12-22 16:10:16 by MS

Fredderic suggested in c.l.t [L1 ] that absolute references to proc-local variables might be useful. It is of course necessary for such references to cease to be valid when the proc returns.

I propose here a small implementation of such things (NOT TESTED!):

  • 'set ref [::REF:: myVar] will create a global variable named $ref that is linked to the local variable myVar
  • a variable REFERENCES is created in caller's scope, with unset traces that cleanup all references created in its scope. These will be triggered by the caller returning.

This is quite simplistic, a proper implementation needs some more care. For instance, references to namespace variables do not need this machinery and a FQ name is what should be returned.

namespace eval REF {
    variable count 0
    proc {} varName {
	# Create a namespace variable to store the local's data, intitialize it
	# with localvar's value and create a simple alias for it in the context
	# of the current proc

	upvar 1 $varName localVar

	if {[array exists localVar]} {
	    # this does not (yet?) work for arrays: need more work in the
	    # transfer of values and traces

	    return -code error "REF: references to array \"$varName\" not yet implemented"
	}

	set callerIsProc [

	variable count
	set refName ::REF::ref_[incr count]
	upvar 0 $refName ref
	set ref $localVar

	# Transfer any traces from localVar to ref

	foreach t [trace info variable localVar] {
	    trace add variable ref {*}$t
	    trace remove variable localVar $t
	}

	# Now unset localVar and link it in the caller to the newly created
	# reference

	unset localVar
	uplevel 1 [list upvar #0 $refName $varName]


	# Insure that the reference is cleaned up when the caller exits

	upvar 1 REFERENCES allRefs
	trace add variable allrefs unset "unset -nocomplain ::REF::$refName ;#"
	
	return $refName
    }

enter categories here