Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Namespace context missing in trace variable

59 views
Skip to first unread message

tombert

unread,
Jun 22, 2015, 5:54:51 AM6/22/15
to
Hi All,

I was trying to trace a NS (origin) variable from another NS (testns). But when the CommandPrefix procedure is triggered, it is without the NS context - Instead of "origin::myvar1" it gets "myvar1" only.

The manual says: "CommandPrefix executes in the same context as the code that invoked the traced operation" but simply adding a "variable $name" inside the CommandPrefix "proc global" does not help.

A workaround would be adding some custom command parameters to the "CommandPrefix" but I was hoping for a better explanation if I am doing something wrong.


Regards
Thomas


namespace eval origin {
namespace ensemble create
namespace export set
variable myvar1 0

proc set args {
foreach {name value} $args {
variable $name
::set $name $value
}
}
}

namespace eval testns {
namespace ensemble create
namespace export register

namespace eval register {
namespace ensemble create
namespace export global

proc global {args} {
foreach name $args {
uplevel #0 [list trace add variable $name write [list testns::sync::global]]
}
}
}

namespace eval sync {
namespace ensemble create
namespace export global

proc global {name index op} {
## where is the context!?
## error: can't read "myvar1": no such variable
puts "'$name' was changed to '[set $name]'"
}
}
}

testns register global origin::myvar1
origin set myvar1 something

Don Porter

unread,
Jun 24, 2015, 9:29:08 AM6/24/15
to
On 06/22/2015 05:54 AM, tombert wrote:
> Hi All,
>
> I was trying to trace a NS (origin) variable from another NS (testns). But when the CommandPrefix procedure is triggered, it is without the NS context - Instead of "origin::myvar1" it gets "myvar1" only.
>
> The manual says: "CommandPrefix executes in the same context as the code that invoked the traced operation" but simply adding a "variable $name" inside the CommandPrefix "proc global" does not help.
>
> A workaround would be adding some custom command parameters to the "CommandPrefix" but I was hoping for a better explanation if I am doing something wrong.

Quick answer: you need to use [upvar].

--
| Don Porter Applied and Computational Mathematics Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

tombert

unread,
Jun 24, 2015, 10:54:13 AM6/24/15
to
On Wednesday, 24 June 2015 15:29:08 UTC+2, Don Porter wrote:
> On 06/22/2015 05:54 AM, tombert wrote:
> > Hi All,
> >
> > I was trying to trace a NS (origin) variable from another NS (testns). But when the CommandPrefix procedure is triggered, it is without the NS context - Instead of "origin::myvar1" it gets "myvar1" only.
> >
> > The manual says: "CommandPrefix executes in the same context as the code that invoked the traced operation" but simply adding a "variable $name" inside the CommandPrefix "proc global" does not help.
> >
> > A workaround would be adding some custom command parameters to the "CommandPrefix" but I was hoping for a better explanation if I am doing something wrong.
>
> Quick answer: you need to use [upvar].
>
> --
> | Don Porter Applied and Computational Mathematics Division |
> | donald dot porter et nist.gov Information Technology Laboratory |
> | http://math.nist.gov/~DPorter/ NIST |
> |______________________________________________________________________|

thx, this helped a little bit. Still I do not get the context. I tried using uplevel, then call [namespace current] but it returns the context of "testns::sync". Wheras I expect it to be "origin".

proc global {name index op} {
uplevel 1 [list
puts [namespace current] ;# returns wrong context
puts "'$name' was changed to '[set $name]'" ;# error no such variable
]
}



And I tried [upvar]. Here I can read the correct value of "myvar". But the request to [namespace which -variable myvar] results in an empty string.

proc global {name index op} {
upvar $name myvar
puts [namespace which -variable myvar] ;# returns an emtpy string
puts "'$name' was changed to '[set $name]'" ;# returns correct value
}


When reading the manual "CommandPrefix executes in the same context as the code that invoked the traced operation" I would expect either [uplevel] or [upvar] together with [namespace current] or [namespace which -variable] to get the actual context returned.


thx

Don Porter

unread,
Jun 24, 2015, 12:08:35 PM6/24/15
to
On 06/24/2015 10:54 AM, tombert wrote:

>>> The manual says: "CommandPrefix executes in the same context as the code that invoked the traced operation" but simply adding a "variable $name" inside the CommandPrefix "proc global" does not help.

Don Porter wrote:
>> Quick answer: you need to use [upvar].

On 06/24/2015 10:54 AM, tombert wrote:>
> proc global {name index op} {
> uplevel 1 [list
> puts [namespace current] ;# returns wrong context
> puts "'$name' was changed to '[set $name]'" ;# error no such variable
> ]
> }

That's not a proper use of [uplevel]. Apply Tcl substitution rules to
see that [namespace current] is evaluated locally.

> proc global {name index op} {
> upvar $name myvar
> puts [namespace which -variable myvar] ;# returns an emtpy string
> puts "'$name' was changed to '[set $name]'" ;# returns correct value
> }

What you want is

proc global {name index op} {
upvar 1 $name myvar
puts [uplevel 1 [list ::namespace which -variable $name]]
puts "'$name' was changed to '$myvar'"
}

--
| Don Porter Applied and Computational Mathematics Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

tombert

unread,
Jul 2, 2015, 12:40:05 PM7/2/15
to
thx for your support. got it now.
0 new messages