红宝石+ Tk 命令绑定 - 范围问题?

发布于 2024-08-11 04:13:45 字数 737 浏览 5 评论 0 原文

所以我有这个应用程序

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

那么它就可以工作。但为什么?

So I have this app

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

But if I press the button, I get "NameError: undefined local variable or method `my_fancy_function' for #<TkButton:..."

I'm pretty sure I'm missing something trivial related to scope... how do I bind that command to the button correctly?

Edit: Okay, if I change my my_fancy_button block to parameters, i.e.

my_fancy_button = TkButton.new(frame, :text => "Press meee", :command => proc{my_fancy_function}).pack

Then it works. But why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狠疯拽 2024-08-18 04:13:45

如果您将 a

p self

放入代码的 do ... end 块中,那么您可能会发现当前范围与您的 Foo 对象不同。

If you put a

p self

into the do ... end block of your code, then you'll probably find out that the current scope is different than your Foo object.

知你几分 2024-08-18 04:13:45

通常,无需将块传递给 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)有效。

Usually, passing blocks to Tk constructors is unnecessary. The resulting scope is confusing, so I think it should be discouraged.

Examples of same which contain only literal values are inflexible, and teach a bad habit.

Here, a minimal change to your program makes it work, while maintaining readability:

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

It works for me using Ruby 2.2.5 (with Tk 8.5.12) on Windows 7.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文