1

呼び出し元の名前空間から変数にアクセス、読み取り、変更できるプロシージャが必要です。変数は と呼ばれ_current_selectionます。いくつかの異なる方法を使用してそれを実行しようとしましupvarたが、何も機能しませんでした。upvar(メカニズムをテストするためだけに小さなテスト proc を作成しました)。これが私の試みです:


proc の呼び出し:

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]
}

私の2回目の試みでは:

proc の呼び出し:

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 に答える