# TkTimer and calling own methods from handler

**URL:** <https://www.ruby-forum.com/t/tktimer-and-calling-own-methods-from-handler/112619>\
**Category:** Ruby\
**Created:** [August 21, 2007, 2:17pm UTC](https://www.ruby-forum.com/t/tktimer-and-calling-own-methods-from-handler/112619 "2007-08-21T14:17:15Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![viciu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/7ba0ec/32.png) [@viciu](https://www.ruby-forum.com/u/viciu)\
**Post date:** [August 21, 2007, 2:17pm UTC](https://www.ruby-forum.com/t/tktimer-and-calling-own-methods-from-handler/112619/1 "2007-08-21T14:17:15Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![viciu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/7ba0ec/32.png) [@viciu](https://www.ruby-forum.com/u/viciu)\
**Post date:** [August 21, 2007, 8:46pm UTC](https://www.ruby-forum.com/t/tktimer-and-calling-own-methods-from-handler/112619/2 "2007-08-21T20:46:39Z")

</div>

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
