TkRoot块中的标题方法在Ruby中如何工作?

时间:2019-05-12 22:52:38

标签: ruby tk

我知道这是一个奇怪的问题。但是,我在思考如何在TkRoot.new { title('Something') }

内定义一个称为title的方法时,一直scratch不休。

好的,这是示例代码:

#!/usr/bin/ruby
require 'tk'

p defined?(title)    # => nil
root = TkRoot.new { p defined?(title) } # writes "method" to stdout.

Here's a link to the official guide

我研究了源代码,它看起来非常混乱(也许充满了使代码难以阅读的所有不良做法),并且在打开所有警告时都充满了警告。

我的问题是方法定义如何仅在块内起作用?我可以在这里得到一个小的示例代码,该示例代码显示如何将方法定义仅限制为一个块吗?

1 个答案:

答案 0 :(得分:4)

这个黑魔法的钥匙是instance_eval,它将在其接收者的语境中评估该区块。通常,块中的self将由范围决定; instance_eval会将其块内的self更改为收到instance_eval消息的任何内容。

class Dog
  def bark
    puts "Woof"
  end

  def initialize(&block)
    instance_eval(&block)
  end
end

Dog.new { bark }
# => "Woof"

在这种情况下,instance_eval(&block)self.instance_eval(&block)相同,这意味着块内的self将是Dog实例;那么bark当然是self.bark,其中selfDog

有一种流派认为instance_evalharmful。我同意最好将它的使用限制为明确划定的DSL。即它可能适用于TK,RSpec或Sinatra,但是如果您认为它很酷并且想要使用它,那么请三思而后行。