1

我需要一个能够从调用者的命名空间访问、读取和更改变量的过程。该变量称为_current_selection。我尝试以upvar几种不同的方式使用它,但没有任何效果。(我写了一个小的测试过程只是为了测试upvar机制)。这是我的尝试:


调用过程:

select_shape $this _current_selection

过程:

proc select_shape {main_gui var_name} {
    upvar  $var_name curr_sel
    puts " previously changed:  $curr_sel"
    set curr_sel [$curr_sel + 1]
}

对于我的第二次尝试:

调用过程:

select_shape $this

过程:

proc select_shape {main_gui} {
    upvar  _current_selection curr_sel
    puts " previously changed:  $curr_sel"
    set curr_sel [$curr_sel + 1]
}

在所有尝试中,一旦它到达代码中的这个区域,它就会说can't read "curr_sel": no such variable

我究竟做错了什么?

编辑:

该函数的调用是通过以下bind命令进行的:

$this/zinc bind current <Button-1> [list select_shape $this _current_selection]

一开始我以为没关系。但也许确实如此。

4

3 回答 3

4

我相信bind命令在全局命名空间中运行,因此预计可以在此处找到变量。这可能有效:

$this/zinc bind current <Button-1> \
    [list select_shape $this [namespace current]::_current_selection]
于 2011-10-21T12:40:05.010 回答
3

要使 upvar 工作,该变量必须存在于您调用它的范围内。请考虑以下事项:

proc t {varName} {
   upvar $varName var
   puts $var
}

#set x 1
t x

如果您按原样运行它,您将收到您报告的错误,取消注释set x 1行,它将起作用。

于 2011-10-21T09:49:54.380 回答
0

在下面的示例中,我试图涵盖从其他命名空间更改变量的大多数变体。它 100% 对我有用。也许会有所帮助。

proc select_shape {main_gui var_name} {
    upvar  $var_name curr_sel
    puts " previously changed:  $curr_sel"
    incr curr_sel
}

namespace eval N {
  variable _current_selection 1
  variable this "some_value"

  proc testN1 {} {
    variable _current_selection
    variable this
    select_shape $this _current_selection
    puts " new: $_current_selection"
  }

  # using absolute namespace name
  proc testN2 {} {
    select_shape [set [namespace current]::this] [namespace current]::_current_selection
    puts " new: [set [namespace current]::_current_selection]"
  }

  select_shape $this _current_selection
  puts " new: $_current_selection"
}

N::testN1
N::testN2

#-------------------------------------
# Example with Itcl class
package require Itcl

itcl::class C {
  private variable _current_selection 10

  public method testC {} {
    select_shape $this [itcl::scope _current_selection]
    puts " new: $_current_selection"
  }
}

set c [C #auto]
$c testC
于 2011-10-21T10:10:06.133 回答