Ticket UUID: | 5edbc4a9f40bd2cfce24e291fc57dea51b7f1a50 | |||
Title: | It's not possible to manipulate complex data structures inside procs | |||
Type: | Bug | Version: | 8.6 | |
Submitter: | anonymous | Created on: | 2015-09-04 03:44:01 | |
Subsystem: | 10. Objects | Assigned To: | nobody | |
Priority: | 5 Medium | Severity: | Minor | |
Status: | Closed | Last Modified: | 2015-09-04 10:38:11 | |
Resolution: | Invalid | Closed By: | ferrieux | |
Closed on: | 2015-09-04 10:38:11 | |||
Description: |
In the next code, it's not possible to make manipulations in place, because the reference count is greater than 1. Another possibility is that ::tcl::unsupported::representation lies, and shows the pointer of another object. I am getting this output: value is a pure string with a refcount of 4, object pointer at 0x8528378, string representation "data" value is a pure string with a refcount of 5, object pointer at 0x8528378, string representation "data" This is the code: proc test {} { set variable_name data puts [::tcl::unsupported::representation $variable_name] } test namespace eval A { variable var_A data puts [::tcl::unsupported::representation $var_A] } | |||
User Comments: |
ferrieux added on 2015-09-04 10:38:11:
Extra references hide in some unconspicuous places: - on the stack when you pass the value as argument - on literals - on hidden stack levels in case of [interp alias] - etc. In your case, the one that's striking is the literal. Use [expr rand()] to generate a value that will not be stored as a literal. Then of course the var itself holds a reference. To nuke that one too, use the K-free-K idiom $x[unset x]. Wrapping up: % proc f {} {set x [expr rand()];puts [tcl::unsupported::representation $x[unset x]]} % f value is a double with a refcount of 1, object pointer at 0x8fe4ec0, internal representation 0x1cfea9a0:0x3fef54d0, no string representation % namespace eval B { variable var_B [expr rand()] puts [tcl::unsupported::representation $var_B[unset var_B]] } value is a double with a refcount of 1, object pointer at 0x86e9910, internal representation 0xab242eb7:0x3fc2175b, no string representation sebres added on 2015-09-04 08:24:08: > it's not possible to make manipulations in place What did you mean here under manipulations? That is expected in tcl, that some "static" code objects has a refCount greater as 1, despite you see this object only once, because of interp/namespace literals, code compiling etc. Guaranteed refCount = 1 you're going to get, if it will be created and returned to interpreter inside any command, and will be used nowhere otherwise. Example: proc test {} { puts [::tcl::unsupported::representation [linsert {} end 1 2 3]] puts [::tcl::unsupported::representation [string tolower DATA]] } Furthermore you can always create a duplicate with refCount = 1, using function Tcl_DuplicateObj. Manipulation of object with refCount > 1 is allowed also, for example change to your own Tcl_ObjType (internal representation), but only if it string representation will be not changed or can be always regenerated to the same within your own Tcl_ObjType. An example for such "complex data structures" are objects contains file/channel/database "handles" etc. So long it's not clear as a bug, I will close this issue as invalid. Please provide more info if expected. |