无法在 Tcl 中使用 upvar 将变量传递给过程

发布于 2024-12-11 13:21:04 字数 1049 浏览 0 评论 0原文

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


call to proc:

select_shape $this _current_selection

proc:

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

对于我的第二次尝试:

call to proc:

select_shape $this

proc:

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变量

我做错了什么?

编辑:

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

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

一开始我认为这并不重要。但也许确实如此。

I need a procedure that will be able to access, read and change a variable from the namespace of the caller. The variable is called _current_selection. I have tried to do it using upvar in several different ways, but nothing worked. (I've written small test proc just to test the upvar mechanism). Here are my attempts:


call to proc:

select_shape $this _current_selection

proc:

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

For my second attempt:

call to proc:

select_shape $this

proc:

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

In all the attempts, once it reaches this area in the code it says can't read "curr_sel": no such variable

What am I doing wrong?

EDIT:

The call for the function is made from a bind command:

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

at start I thought that it doesn't matter. but maybe It does.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

等风来 2024-12-18 13:21:04

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

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

I believe that bind commands operate in the global namespace, so that's where the variable is expected to be found. This might work:

$this/zinc bind current <Button-1> \
    [list select_shape $this [namespace current]::_current_selection]
太傻旳人生 2024-12-18 13:21:04

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

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

#set x 1
t x

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

for upvar to work the variable must exist in the scope that you are calling it in. consider the following:

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

#set x 1
t x

If you run it as it is you'll get the error you are reporting, uncomment the set x 1 line and it will work.

如果没结果 2024-12-18 13:21:04

在下面的示例中,我尝试涵盖从其他名称空间更改变量的大多数变体。它 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

In the example below I've tried to cover the most variants of changing variables from other namespace. It 100% works for me. Maybe it will help.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文