所以我有这个应用程序
require 'tk'
class Foo
def my_fancy_function
puts "hello, world!"
end
def initialize
@root = TkRoot.new{title "Hello, world!"}
frame = TkFrame.new
my_fancy_button = TkButton.new(frame) do
text "Press meee"
command {my_fancy_function}
pack
end
frame.pack
Tk.mainloop
end
end
bar = Foo.new
但是如果我按下按钮,我会得到“NameError:未定义的局部变量或方法`my_fancy_function'for#<TkButton:...”
我很确定我错过了与范围相关的微不足道的事情......如何正确地将该命令绑定到按钮?
编辑:好的,如果我将我的my_fancy_button
块更改为参数,即
my_fancy_button = TkButton.new(frame, :text => "Press meee", :command => proc{my_fancy_function}).pack
然后它工作。但为什么?
如果你放一个
p self
进入代码的do ... end
块,然后您可能会发现当前范围与您的Foo
对象不同。
通常,将块传递给Tk
构造函数是不必要的。由此产生的范围令人困惑,所以我认为不应该气馁。
仅包含字面值的相同示例是不灵活的,并教导一个坏习惯。
在这里,对程序进行最小程度的更改使其工作,同时保持可读性:
require 'tk'
class Foo
def my_fancy_function
puts "hello, world!"
end
def initialize
@root = TkRoot.new{title "Hello, world!"}
frame = TkFrame.new
my_fancy_button = begin
b = TkButton.new frame
b.text "Press meee"
b.command {my_fancy_function}
b.pack
end
frame.pack
Tk.mainloop
end
end
bar = Foo.new
它适用于我在Windows 7上使用Ruby 2.2.5(使用Tk 8.5.12)。