まつもと ゆきひろです.
In message "[ruby-list:1835] command option of Tk"
on 97/01/23, Noritugu Nakamura <nnakamur / tamaru.kuee.kyoto-u.ac.jp> writes:
|中村です。
うーん,中村さん,いつ寝てるんですか? ゆうべ徹夜しちゃった
んでしょうか? 体壊さないでくださいね.
|とりあえず、こういうのを書きましたが
|どちらのボタンを押しても 2 しか出ません。
|
|#!/usr/local/bin/ruby
|
|require "tk"
|
|for i in 1..2
| text = "button" + i
| TkButton.new {
| text text
| command proc {
| print i, "\n"
| STDOUT.flush
| }
| pack
| }
|end
|
|Tk.mainloop
以下のように書き換えてください.
for i in 1..2
text = "button" + i
TkButton.new {
text text
j = i # ここが大事
command proc {
print j, "\n" # iでなくjをつかう
STDOUT.flush
}
pack
}
end
この点はちょっと難しいので説明しましょう.
つまりtclでは文字列はその場で展開されてしまうため,-command
で指定した$iの値はその時点の$iの値です.ところがrubyでは評価
は必ず実行時(ボタンが押された時)ですから,その時点のiの値(ルー
プの実行が終って2になっている)が表示されます.tclでいうと
"puts $i"でなく{puts $i}を指定した感じでしょうか.
望ましい処理はcommandを指定した時点でのiの値を保存しておくこ
とです.こういう時に動的変数を使います.動的変数(イテレータ
ブロックの中で最初に宣言された変数)はそのイテレータブロック
の範囲内だけがスコープになります.つまりループの1回目の実行
と2回目の実行で,iは同じもの(値も共有する)ですが,jは一度ス
コープを抜けて再度生成されたもので別々の値を持ちます.
Procが絡まない時には動的変数かどうかはほとんど違いがないので
すが,Procが関係すると(Procはそのスコープでの変数の値を保存
するので)結構ややこしくなります.難しければ,また質問してく
ださい.
まつもと ゆきひろ /:|)