From: Hiroshi IGARASHI Date: 2000-05-11T10:57:08+09:00 Subject: [ruby-list:22444] Re: about Gtk::RadioMenuItem いがらしです。 すでにやすしさんからfollowがありましたが、 書きかけていたので出しちゃいます。 御質問の件そのものは、たぶんRuby/GTKと無関係です。 At Mon, 8 May 2000 11:13:29 +0900, in [ruby-list:22374] about Gtk::RadioMenuItem, goto@yokogawa-kouji.co.jp wrote: > > 以下にサンプルを付けますが、forループでMenuItemを生成する場合 > と、それぞれ単独でMenuItemを生成する場合とで、挙動が違います。 > 何が違っているのでしょうか。 (snip) > for i in 0..2 > j = i + 1 > buf[i] = sprintf("item %2d - %d", depth, j) > menuitem[i] = Gtk::RadioMenuItem::new(group, buf[i]) > menuitem[i].signal_connect("activate")do > p buf[i] > end ここが問題の箇所です。 signal_connectに渡しているブロックの中でブロック外の変数iを 参照していますが、外側のfor式の実行を終えた後、iの指す値は 2になっています。ブロックは(オブジェクトそのものではなく) 外側の環境を保持しているので、シグナルが発生しブロックが 呼ばれたときに変数iを参照すると、その値は「ちゃんと」2に なっているわけです。 menuitem[i].signal_connect("activate", i) do |w, k| p buf[k] end とすることで、変数iが変更される影響を受けなくなります。 このsignal_connectの使い方については、 過去記事[ruby-list:15711]から始まるスレッドも参照して下さい。 ただ上記のように修正しても、選択されなくなったMenuItemと 新たに選択されたMenuItemの両者に対応するブロックが呼ばれて しまうと思います。例えば"item 1 - 1"が選ばれていて "item 1 - 2"を選択した場合 iga@runal> ruby -I ../src radiomenuitem2.rb "item 1 - 1" "item 1 - 2" となってしまいます。 期待される動作は、新たに選択されたMenuItem のブロックだけが呼ばれる、というものだと思います。 同様のプログラムをC/GTKで書いてもそうなりますし。 これは[ruby-list:21732]でも報告されていましたが (見落としてました。すみません)、たぶんRuby/GTKのバグです。 # 原因が分かる方はruby-extで教えて下さい。 -- 五十嵐 宏 (Hiroshi IGARASHI)