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.

> 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()

<snip>

> So how I should call own methods?

One solution is to use real global variables.

<code>
#!/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
</code>

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

<code>
#!/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
</code>

Regards, Morton