TkRoot 块中的 title 方法如何在 Ruby 中工作?
How does title method inside TkRoot block work in Ruby?
我知道这是个奇怪的问题。但是一想到TkRoot.new { title('Something') }
里面怎么定义了一个叫做title的方法,我就一直抓耳挠腮
好的,下面是示例代码:
#!/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
我查看了源代码,它看起来非常混乱(并且可能充满了使代码更难阅读的所有不良做法)并且在所有警告都打开时充满了警告。
我的问题是方法定义如何只在块内工作?我可以在这里得到一个小的示例代码来说明如何将方法定义限制在一个块中吗?
这个黑魔法的关键是 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
,其中 self
就是 Dog
.
有一派认为instance_eval
是harmful。我同意最好将其使用限制在明确界定的 DSL 中。 IE。它可能适用于 TK、RSpec 或 Sinatra,但如果您认为它很酷并想使用它,最好三思而后行。
我知道这是个奇怪的问题。但是一想到TkRoot.new { title('Something') }
好的,下面是示例代码:
#!/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
我查看了源代码,它看起来非常混乱(并且可能充满了使代码更难阅读的所有不良做法)并且在所有警告都打开时充满了警告。
我的问题是方法定义如何只在块内工作?我可以在这里得到一个小的示例代码来说明如何将方法定义限制在一个块中吗?
这个黑魔法的关键是 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
,其中 self
就是 Dog
.
有一派认为instance_eval
是harmful。我同意最好将其使用限制在明确界定的 DSL 中。 IE。它可能适用于 TK、RSpec 或 Sinatra,但如果您认为它很酷并想使用它,最好三思而后行。