The following code creates 3 buttons and adds a handler to each one. The Quit button works, the Give Up button produces an error NameError unknown option settings_change and suggests that an object has been deleted. Same with the Next button. The code works ok when I put the event handlers outside the class.
It turns out that if a callback is created by first doing something like next_note_proc = proc {next_note}, then in the button creation do command next_note_proc. Why does this work??
Why do the callbacks work differently when inside or outside the class?
require 'tk'
require 'tkextlib/tile'
class App
def next_note
puts "Got next note"
end
def settings_change
puts "Got settings change"
end
def quit
puts "Got exit"
exit(1)
end
def initialize
$number_correct = TkVariable.new;
$mode = TkVariable.new
@root = TkRoot.new {title "Music Training"}
@content = Tk::Tile::Frame.new(@root) {padding "0 0 0 0"}.grid( :sticky => 'nsew')
@a = Tk::Tile::Button.new(@content) {text 'Next'; command {next_note}}.grid( :column => 1, :row => 1, :sticky => 'w')
@b = Tk::Tile::Button.new(@content) {text 'Give up'; command {settings_change}}.grid( :column => 2, :row => 1, :sticky => 'w')
@c = Tk::Tile::Button.new(@content) {text 'Quit'; command {quit}}.grid( :column => 2, :row => 2, :sticky => 'w')
TkWinfo.children(@content).each {|w| TkGrid.configure w, :padx => 0, :pady => 0}
@c.bind("1") {quit}
@a.bind("1") {next_note}
@b.bind("1") {settings_change}
puts "Starting up"
end
def run
Tk.mainloop
end
end
the_app = App.new
the_app.run
Commands executed from buttons run in the global context, but
settings_change,quitandnext_noteare in the context of the class. When you use theproccommand it creates a newProcobject which calls the method, and which can be called from other contexts.The reason the
quitcommand seems to work is probably because there is anotherquitcommand at the global scope that is getting called — it is almost certainly not calling thequitmethod of theAppobject. You can verify that by adding a print statement in thequitmethod.