TkTimer and calling own methods from handler

Hi!
I’m experimenting with Ruby Tcl/Tk and I’ve got stuck with timers. I
reduced my problem to following example:

#!/usr/bin/env ruby
require “tk”

def advance
button.text = global_var.to_s
global_var += 1
end

global_var = 0

root = TkRoot.new(:title=>‘Example’)
button = TkButton.new(root) {
text “button”
}
button.pack(“side”=>“right”, “fill”=>“y”)
tick = proc{|aobj|
advance
}
timer = TkTimer.new(250, -1,tick )
timer.start(0)

Tk.mainloop()

I want this code to increase number displayed on button, but does not
work. When I change timer definition to:

tick = proc{|aobj|
button.text = global_var.to_s
global_var += 1
}

It does work, so it looks like I need to call my own method some
special way? I have examined examples in Ruby source code, but all of
them operates without wrapping code in own methods (I suppose to make
it easier to understand).

So how I should call own methods?

On Aug 21, 2007, at 8:15 AM, NetManiac wrote:

I’m experimenting with Ruby Tcl/Tk and I’ve got stuck with timers. I
reduced my problem to following example:

#!/usr/bin/env ruby
require “tk”

def advance
button.text = global_var.to_s
global_var += 1
end

Both variables (button and global_variable) are local to the advance
method and are not the same as the local variables button and
global_variable defined below. This is the source of your problem.

timer = TkTimer.new(250, -1,tick )
timer.start(0)

Tk.mainloop()

So how I should call own methods?

One solution is to use real global variables.

#!/usr/bin/env ruby require "tk"

def advance
$button.text = $global_var.to_s
$global_var += 1
end

$global_var = 0

root = Tk.root
root.title(‘Example’)
win_w, win_h, win_y = 150, 50, 50
win_x = (root.winfo_screenwidth - win_w) / 2
root.geometry("#{win_w}x#{win_h}+#{win_x}+#{win_y}")
root.resizable(false, false)

$button = TkButton.new(root, :text => “button”)
$button.pack(:fill => :both, :expand => true)
TkTimer.new(250, -1) { advance }.start

Tk.mainloop

Another, and IMO better, solution is take advantage of Ruby being
object-oriented.

#!/usr/bin/env ruby require "tk"

class MyButton
def initialize(parent)
@count = 0
@me = TkButton.new(parent).pack(:fill => :both, :expand => true)
TkTimer.new(250, -1) { advance }.start
end
def advance
@count += 1
@me.text(@count.to_s)
end
end

root = Tk.root
root.title(‘Example’)
win_w, win_h, win_y = 150, 50, 50
win_x = (root.winfo_screenwidth - win_w) / 2
root.geometry("#{win_w}x#{win_h}+#{win_x}+#{win_y}")
root.resizable(false, false)

MyButton.new(root)

Tk.mainloop

Regards, Morton