はじめまして、surmeと申します。
ruby/gtkを使っていて納得いかないことが起きたので質問させてください。

以下に添付したscriptで、Gtk::timeout_addに渡すブロックで呼ばれる
timeout_test関数がうまく動いてくれません。
(1)の位置で$counterをインクリメントするとtimeout_testは一回しか
機能しないようです。(2)の位置ですと正常に動作するにはしますが、
インクリメントのタイミングが望み通りではないのです。
もちろん$counterを1で初期化するなど回避はいくらでもできるのですが、
これが仕様だと嬉しくないなぁ、と思います。

さらに、
if $counter == 10
  stop_timeout_test
  Gtk.main_quit
end
のような条件文を入れて、自動的にダイアログを閉じさせようとすると、
timeout_testの先頭に入れたときには正常に動作しますが、
timeout_testの末尾に入れると動きません。
(このとき$counterのインクリメントは(2)の位置で行っています。)

以上の動作はbug?それとも仕様でしょうか?
他にもうまく動作しないことがあるのですが、とりあえず以上のケースが
特定できましたので報告します。
環境は
ruby1.4.6 + ruby-gtk0.23
ruby1.4.6 + ruby-gtk0.24(20010303)
ruby1.6.2 + ruby-gtk0.24(20010303)
です。
よろしくお願いします。
--
                                    surme <CZU13166 / nifty.com>

----------------------------------------
#!/usr/bin/ruby

require 'gtk'

Interval = 100
$counter = 0
$timer = nil


def start_timeout_test
  $timer = Gtk::timeout_add(Interval) { timeout_test } if $timer.nil?
end
	
def stop_timeout_test
  unless $timer.nil?
    Gtk::timeout_remove($timer)
    $timer = nil
  end
end

def timeout_test

#if counter incrementation is done here, timeout works at only first time.
# $counter += 1      #####(1)#####

  $label.set "count: #{$counter}" 

#incrementing here doesn't influence to timeout,
#but I want increment correctly... 
  $counter += 1      #####(2)#####

end
		
dlg = Gtk::Dialog.new
  $label = Gtk::Label.new("count: 0")
dlg.vbox.pack_start $label

button = Gtk::Button.new("close")
button.signal_connect("clicked") {
  stop_timeout_test
  Gtk.main_quit
}
dlg.action_area.pack_start button

button1 = Gtk::Button.new("start")
button1.signal_connect("clicked") { start_timeout_test }
dlg.action_area.pack_start button1

button2 = Gtk::Button.new("stop")
button2.signal_connect("clicked") { stop_timeout_test }
dlg.action_area.pack_start button2

dlg.show_all
Gtk.main